【发布时间】:2020-04-21 12:11:16
【问题描述】:
直到今天,我都认为我对继承的理解比我显然理解的要好得多。此示例的目标是设计一个包含 n 个类(在本例中为 3 个)的框架,每个类在程序的生命周期中都应该唯一存在。第四个类的实现将包含全局 main 函数,它将负责为其他类处理内存。此外,我希望保护基类中的公共成员,以防止任何其他类调用它们。
目前,“Main”类中的继承以及每个基类中的“protected:”关键字都被注释掉了。它并不完全符合我的要求,但一切正常。构造函数被调用一次(按升序),每个函数都被调用,然后是析构函数。
我在这里的困惑实际上是双重的。如果取消注释 Main 类中的继承,代码会编译,但 new 每个 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;
}
如果有人好奇,我一直在尝试使用 gcc v8.3 编译器在 ideone.com 上编译它。
【问题讨论】:
-
这是否回答了您问题的第二部分stackoverflow.com/questions/16785069/…?
-
如果我正确理解你的问题,也是第一部分,是的,如果你取消公共注释,它会调用构造函数两次,因为在你的代码中
Main::Main(A *a, B *b, C *c)调用构造函数A::A(),B::B(),@987654328 @ 是从派生类Main隐含的。 -
确实如此。我想我理解抽象类应该在继承成员时引用它的逻辑,但这并不是那么直观。似乎应该在文档或教程中更好地解释这一点。
-
您混淆了继承(is-a 关系)和组合(has-a 关系)。如果
Main继承自A,那么您就是在表达Main是一个A。如果你给Main一个A类型的成员(或std::unique_ptr),那么你就是在表达Main有一个A。您想要两者中的哪一个取决于您要为类提供的语义,但您可能不想要both。没有更多细节,很难说出你想要哪个。另见例如this question.
标签: c++ inheritance constructor protected