До сегодняшнего дня я думал, что разбираюсь в наследовании намного лучше, чем кажется на самом деле. Цель этого примера состояла в том, чтобы спроектировать структуру из n классов (в данном случае 3), каждый из которых должен существовать уникально на протяжении всей жизни программы. Четвертый класс, реализация которого будет содержать глобальную основную функцию, будет отвечать за обработку памяти для других классов. Кроме того, я надеялся защитить общедоступные члены в базовых классах, чтобы любой другой класс не мог их вызывать.
В настоящее время закомментировано наследование в классе «Main», а также ключевые слова «protected:» в каждом из базовых классов. Это не совсем то, что я хочу, но все ведет себя как обычно. Конструкторы вызываются один раз (в порядке возрастания), после каждой функции вызывается деструктор.
Мое замешательство здесь на самом деле двоякое. Если вы раскомментируете наследование в классе Main, код компилируется, но новый каждый ctor/dtor вызывается дважды, сначала в порядке возрастания, а затем в порядке убывания. Я не смог объяснить, почему это могло произойти, но это не кажется правильным. Каждое объяснение наследования, которое я когда-либо видел, расплывчато и не объясняет, почему это должно произойти.
class Main //: public A, public B, public C
Второй момент, который меня смущает, — это защищенные члены классов. Я думаю, что если я раскомментирую ключевые слова «защищено:», продолжая методы в базовых классах, я смогу вызывать их из унаследованных классов. Насколько я понимаю, я даже должен иметь возможность наследовать их как частные, предполагая, что я хочу, чтобы эта функциональность была только у детей. Увы, я просто получаю сообщения об ошибках в защищаемом методе.
Я хорошо знаю, что у моего понимания есть серьезные недостатки, но я безуспешно искал объяснение. Мне действительно не помешало бы некоторое конструктивное понимание того, что здесь происходит,
Спасибо,
#include <iostream>
#include <memory>
using namespace std;
class A
{
public:
A() { cout << "Ctor A\n";}
~A() { cout << "Dtor A\n";}
//protected:
void func() { cout << "Function A\n"; }
};
class B
{
public:
B() { cout << "Ctor B\n";}
~B() { cout << "Dtor B\n";}
//protected:
void func() { cout << "Function B\n"; }
};
class C
{
public:
C() { cout << "Ctor C\n";}
~C() { cout << "Dtor C\n";}
//protected:
void func() { cout << "Function C\n"; }
};
class Main //: public A, public B, public C
{
public:
Main(A *a, B *b, C *c);
private:
std::unique_ptr<A> mA;
std::unique_ptr<B> mB;
std::unique_ptr<C> mC;
};
Main::Main(A *a, B *b, C *c) : mA(a), mB(b), mC(c)
{
mA->func();
mB->func();
mC->func();
}
int main()
{
Main m(new A, new B, new C);
return 0;
}
Если кому-то интересно, я пытался скомпилировать это на ideone.com с помощью компилятора gcc v8.3.
Main::Main(A *a, B *b, C *c)
вызов конструкторовA::A()
,B::B()
,C::C()
неявно из производного классаMain
. - person Gaurav Dhiman   schedule 03.01.2020Main
наследуется отA
, то вы выражаете, чтоMain
являетсяA
. Если вы даетеMain
элемент типаA
(илиstd::unique_ptr
ему), то вы выражаете, чтоMain
имеетA
. Какой из двух вы хотите, зависит от семантики, которую вы хотите дать своим классам, но вы, вероятно, не хотите оба. Без более подробной информации трудно сказать, что вы хотите. См. также, например. этот вопрос. - person walnut   schedule 03.01.2020