Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 55, средняя оценка - 4.93
rar14
28 / 22 / 1
Регистрация: 14.04.2009
Сообщений: 448
#1

Наследуются ли конструкторы и деструкторы? - C++

02.06.2009, 14:54. Просмотров 7546. Ответов 124
Метки нет (Все метки)

При наследовании происходит ли наследование конструкторов и деструкторов базового класса?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kzru_hunter
1090 / 765 / 58
Регистрация: 01.02.2011
Сообщений: 1,775
Записей в блоге: 1
13.01.2016, 18:30     Наследуются ли конструкторы и деструкторы? #31
Цитата Сообщение от xecu91 Посмотреть сообщение
Исчерпывающее объяснение здесь.
Я там не увидел объяснения. Где именно? Я там только увидел ошибку в том, что ему нужно явно вызывать конструктор базового класса в конструкторе производного класса.
Croessmah
Модератор
Эксперт CЭксперт С++
13056 / 7319 / 816
Регистрация: 27.09.2012
Сообщений: 18,055
Записей в блоге: 3
Завершенные тесты: 1
13.01.2016, 18:42     Наследуются ли конструкторы и деструкторы? #32
Цитата Сообщение от kzru_hunter Посмотреть сообщение
// этот конструктор можно вызвать, несмотря на то, что так нельзя делать
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
 
class A
{
public:
 
};
 
class B : public A
{
public:
    void func()
    {
       A::A(); // этот конструктор можно вызвать, несмотря на то, что так нельзя делать
       //C::C(); этот конструктор нельзя вызвать
    }
};
 
class C : public A
{
public:
    
};
 
int main()
{
    std::cout << "Hello, world!\n";
}
http://rextester.com/KKWLK56056
xecu91
3 / 3 / 0
Регистрация: 09.01.2012
Сообщений: 28
13.01.2016, 18:44     Наследуются ли конструкторы и деструкторы? #33
Для начала нужно понять, о каком конструкторе идёт речь.

Компилятор может генерировать конструкторы автоматически, например, конструктор по умолчанию. Если он генерирует конструктор по умолчанию для производного класса, то он сам вставит вызов конструктора базового класса. Это можно легко увидеть, выполнив такой код:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
class A {
 public:
    A() {
        std::cout << "A::A()\n";
    }
};
 
class B : public A {
};
 
int main() {
    B b;
    return 0;
}
Если же речь идёт о конструкторе, который не генерируется компилятором автоматически, то вызов конструкторов базового класса - ответственность программиста. Например, следующий код не будет скомпилирован:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>
 
class A {
 public:
    explicit A(int v) {
        std::cout << "A::A(" << v << ")\n";
    }
};
 
class B : public A {
};
 
int main() {
    B b(2);
    return 0;
}
Это и означает, что конструкторы не наследуются. Однако, для достижения некоторого "наследования" конструкторов есть два способа. Первый, соответствующий стандарту C++03:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
 
class A {
 public:
    explicit A(int v) {
        std::cout << "A::A(" << v << ")\n";
    }
};
 
class B : public A {
 public:
    B(int v) : A(v) {
    }
};
 
int main() {
    B b(2);
    return 0;
}
Здесь мы явно вызываем конструктор базового класса в списке инициализации производного класса.

Второй способ, который соответствует стандарту C++11:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <iostream>
 
class A {
 public:
    explicit A(int v) {
        std::cout << "A::A(" << v << ")\n";
    }
};
 
class B : public A {
 public:
    using A::A;
};
 
int main() {
    B b(2);
    return 0;
}
Здесь мы явно говорим, что необходимо унаследовать конструкторы базового класса A.
kzru_hunter
1090 / 765 / 58
Регистрация: 01.02.2011
Сообщений: 1,775
Записей в блоге: 1
13.01.2016, 19:20     Наследуются ли конструкторы и деструкторы? #34
Цитата Сообщение от Croessmah Посмотреть сообщение
http://rextester.com/KKWLK56056
Да, странно как-то это. Но в Visual Studio 2013 без ошибок компилируется (появляется только ошибка intellisense).
C++ Builder 6 не хочет компилить, багнутый, левую ошибку показывает. Но начинает компилить только, когда вручную определяешь конструктор по умолчанию A::A().

xecu91
То что у тебя вначале написано - это не из-за наследования. У каждого класса должны быть свои конструкторы. Если ни один не определён, то генерируется конструктор по умолчанию, в код которого добавляется неявный вызов конструктора по умолчанию базового класса. Но для конструктора по умолчания базового класса стоит модификатор explicit, который требует чтобы его вызывали явно. Поэтому и ошибка. И никак не из-за наследования.

А то что в C++11 добавили так называемый constructor inheritance, то я бы эту возможность назвал так - constructor adoption (заимствование конструктора). И у меня почему-то код не компилится в VS 2013 (вместо конструктора A::A пытается вызвать копирующий конструктор B:B(const B&), но не может т.к. не может преобразовать int в B), хотя rextester компилит.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
13.01.2016, 20:15     Наследуются ли конструкторы и деструкторы? #35
М-да, веселый язык С++! О каких бы самых базовых вещах ни зашла речь, внезапно выясняется, что никто о них не имеет адекватного представления!
hoggy
6437 / 2655 / 460
Регистрация: 15.11.2014
Сообщений: 5,842
Завершенные тесты: 1
13.01.2016, 20:45     Наследуются ли конструкторы и деструкторы? #36
Цитата Сообщение от CheshireCat Посмотреть сообщение
Неверно. Конструкторы и деструкторы не наследуются.
наследуются.
не только конструкторы - весь класс,
со всем своим барахлом.

весь функционал, и все данные.
xecu91
3 / 3 / 0
Регистрация: 09.01.2012
Сообщений: 28
13.01.2016, 21:25     Наследуются ли конструкторы и деструкторы? #37
kzru_hunter, это не так, попробуй убери оттуда explicit и скомпилируй.
rikimaru2013
C++ Game Dev
2419 / 1113 / 240
Регистрация: 30.11.2013
Сообщений: 3,661
13.01.2016, 21:48     Наследуются ли конструкторы и деструкторы? #38
Смотря у кого спрашивают:
- если у мидла: наследник наследует все методы и свойства родителя.
- если у джуна: то не наследуются (конструктор, деструктор, оператор присваения и friend отношения)
mporro
256 / 102 / 14
Регистрация: 04.07.2014
Сообщений: 571
14.01.2016, 01:05     Наследуются ли конструкторы и деструкторы? #39
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Так наследуются или нет?
Нет, не наследуются.
Они могут генерироваться компилятором, но не наследуются.
kzru_hunter
1090 / 765 / 58
Регистрация: 01.02.2011
Сообщений: 1,775
Записей в блоге: 1
14.01.2016, 07:39     Наследуются ли конструкторы и деструкторы? #40
Цитата Сообщение от xecu91 Посмотреть сообщение
это не так, попробуй убери оттуда explicit и скомпилируй.
Да, я там поторопился. Не обратил внимания на то, что там не был определен конструктор по умолчанию. И ошибся насчет explicit: генерируемый по умолчанию конструктор производного класса все-таки может неявно вызвать explicit конструктор по умолчанию базового класса.

Цитата Сообщение от xecu91 Посмотреть сообщение
Если же речь идёт о конструкторе, который не генерируется компилятором автоматически, то вызов конструкторов базового класса - ответственность программиста. Например, следующий код не будет скомпилирован:
....
Это и означает, что конструкторы не наследуются.
В том то и проблема, что я не вижу между этими заключениями никакой связи. Я вижу только то, что в том коде был вручную пользователем определен кастомный конструктор в базовом классе, из-за чего компилятор не сгенерировал конструктор по умолчанию для этого базового класса. Поэтому компилятор и не может сгенерировать конструктор по умолчанию для производного класса, т.к. ему для этого нужен конструктор по умолчания базового класса, а он в свою очередь не был сгененерирован из-за причин, описанных выше. К сожалению, для меня это не означает, что конструкторы не наследуются. Как у вас получилось прийти к такому выводу - я не понимаю.

Цитата Сообщение от mporro Посмотреть сообщение
Они могут генерироваться компилятором, но не наследуются.
почему не наследуются?

Раз Страуструп говорит, что не наследуются, значит скорее всего так и есть.
Но как я говорил, мне не даёт покоя следующее:
C++
1
2
3
4
5
6
7
8
B b;
B h;    
b.A::operator=(h); // можно вызвать оператор присваивания базового класса
 
// можно ещё использовать в производном классе using A::operator=
// и тогда можно просто использовать b = h; <- вызовется A::operator=
 
B *j = (B*)(new B::A()); // можно вызвать конструктор базового класса, но при этом будет создан объект базового класса, а не производного
Может дело в том, как понимать и видеть значение понятия наследования? Пытаюсь увидеть так, как видит Страуструп или Прата, но не получается.
mporro
256 / 102 / 14
Регистрация: 04.07.2014
Сообщений: 571
14.01.2016, 09:14     Наследуются ли конструкторы и деструкторы? #41
kzru_hunter
В С++ наследование делает одновременно два дела: подтип наследует типовую метку супертипа и устанавливает между выведенным классом и базовым классом отношение композиции. Словно бы в В Вы определили поле типа A и разместили там какой-то объект. Это приводит к ужасающей путанице между наследованием и композицией. В частности, C++ позволяет "унаследовать" класс закрытым образом! Это приводит к тому, что два класса входят в отношение композиции, но не в ходят в отношение наследования вообще, а называется эта операция "закрытым наследованием". Также и с конструкторами: они не наследуются, наследовать их было бы крайне глупо, но они агрегируются.

Добавлено через 14 минут
kzru_hunter
Есть ещё такой терминологический изыск: наследование интерфейса и наследование реализации. В этом смысле можно говорить, что интерфейс базовых конструкторов не наследуется, а реализация -- да.

Можно развести дискуссию и на такую тему, что обсуждение наследования конструктора бессмысленно, как деление ноль, так как нельзя сказать, что объект обрабатывает сообщение о своём конструировании, ведь он вообще не создан!
hoggy
6437 / 2655 / 460
Регистрация: 15.11.2014
Сообщений: 5,842
Завершенные тесты: 1
14.01.2016, 09:53     Наследуются ли конструкторы и деструкторы? #42
Цитата Сообщение от kzru_hunter Посмотреть сообщение
В том то и проблема, что я не вижу между этими заключениями никакой связи.
потому что её там нет.
товарищ несет пургу.

Добавлено через 24 минуты
Цитата Сообщение от kzru_hunter Посмотреть сообщение
Может дело в том, как понимать и видеть значение понятия наследования?
возможно одно и только одно понимание, которое не будет противоречить самому себе:
класс А унаследовал от класса Б все

получаем некий Д, который представляет собой плоскую модель [A:Б]
то бишь все от А, и все от Б.

доказательство непротиворечивости:

люди грамотные, и балбесы сходяццо в одном:
наследуются фукнкции-члены, и члены-данные классов.

в частности мы можем позвать функцию член Б, через имя класса А:

C++
1
2
3
4
5
int main(){
    struct B { void foo(){} };
    struct A: B {};
    A a a.foo();
}
теперь вносим функцию-член в приваты:

C++
1
2
3
4
5
int main(){
    class B { void foo(){} };
    struct A: B {};
    A a a.foo(); // error: private
}
внимание вопрос: наследуется ли функция-член foo?
если балбес скажет: нет,
тогда он и начнет противоречить самому себе.

функция-член наследуется.
она просто не доступна в контексте класса наследника.

технически, наследование - это тупо объединение двух (или более) классов в один.

результатом синтеза А и Б является некий Д,
который включает в себя все функции-члены и данные от обоих классов.
при этом все члены обоих классов сосуществуют одновременно.

C++
1
2
3
4
5
6
// данная модель иллюстрирует принцип наследования
template<class T> struct derrived: T {};
struct base {};
 
typedef derrived<base>
    agregat;
агрегат - продукт синтеза (наследования).
плоская модель, которая обладает всем функционалом обоих классов
но при этом не является ни derrived, ни base


все что нужно понять балбесам,
коих в этой теме как минимум несколько:
вопрос не в том, наследуется ли (да, наследуется).
вопрос: а доступен ли?

доступность тех или иных членов классов
определяется правилами языка.

но не техническими ограничениями.

с технической точки зрения любой функционал базового класса,
будь то функция-член, или конструктор
(который, с технической точки зрения так же является функцией)
реально существует.
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
14.01.2016, 10:26     Наследуются ли конструкторы и деструкторы? #43
Цитата Сообщение от mporro Посмотреть сообщение
Также и с конструкторами: они не наследуются, наследовать их было бы крайне глупо, но они агрегируются.
Ну, Страуструп мастер засирать мозги, и его терминология очень противоречива. Изначально наследование означает наследование свойств, однако при закрытом наследовании классов этого не происходит.
Наследование функции, это когда несколько классов разного типа имеют одну и ту же функцию. Но конструкторы классов разных типов по определению имеют разные имена, как же два разных типа могут иметь один и тот же конструктор?
Так что холивар заложен самим автором языка в его противоречивой терминологии.
mporro
256 / 102 / 14
Регистрация: 04.07.2014
Сообщений: 571
14.01.2016, 10:30     Наследуются ли конструкторы и деструкторы? #44
hoggy
Опять у фас какие-то фантазии начинаются, на почве С++

Согласно вашим фантазиям ниже идёт наследование...
C++
1
2
3
4
5
6
7
8
struct TBase {
    void foo();
};
 
struct TDerived {
    TBase b;
    void baz();
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
14.01.2016, 10:33     Наследуются ли конструкторы и деструкторы?
Еще ссылки по теме:
Конструкторы и деструкторы C++
C++ Конструкторы/Деструкторы
Конструкторы и деструкторы C++
C++ Конструкторы и деструкторы
C++ Конструкторы и деструкторы

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Mr.X
Эксперт С++
3048 / 1693 / 265
Регистрация: 03.05.2010
Сообщений: 3,867
14.01.2016, 10:33     Наследуются ли конструкторы и деструкторы? #45
Цитата Сообщение от mporro Посмотреть сообщение
Можно развести дискуссию и на такую тему, что обсуждение наследования конструктора бессмысленно, как деление ноль, так как нельзя сказать, что объект обрабатывает сообщение о своём конструировании, ведь он вообще не создан!
Ну, конструктор инициализирует уже созданный объект, поэтому его можно рассматривать как сообщение "сырому" объекту.
Кстати, здесь у Страуструпа тоже терминологический ляп, так как конструктором он назвал то, что фактически является инициализатором.
Yandex
Объявления
14.01.2016, 10:33     Наследуются ли конструкторы и деструкторы?
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru