对 ctor/dtor 行为与继承 类 的混淆

Confusion about ctor/dtor behavior with inherited classes

直到今天我还认为我比表面上更了解继承。此示例的目标是设计一个包含 n 个 classes(在本例中为 3)的框架,每个框架在程序的生命周期中都应该唯一存在。第四个 class,其实现将包含全局 main 函数,将负责处理其他 classes 的内存。此外,我希望保护基 class 中的 public 成员,以防止任何其他 class 调用它们。

目前,"Main" class 中的继承以及每个基本 class 中的 "protected:" 关键字都被注释掉了。它并不完全符合我的要求,但一切都像正常一样。构造函数被调用一次(按升序),每个函数被调用,然后是析构函数。

我在这里的困惑实际上有两个方面。如果你 un-comment 在 Main class 中继承,代码编译,但 new each ctor/dtor 被调用两次,首先是升序顺序,然后是降序顺序。我一直无法解释为什么会发生这种情况,但它似乎不正确。我所见过的关于继承的每一个解释都是含糊不清的,并没有解释为什么需要发生这种情况。

class Main //: public A, public B, public C

我的第二个困惑点是 classes 的受保护成员。我认为,如果我 un-comment "protected:" 关键字,继续基本 classes 中的方法,我应该能够从继承的 classes 中调用它们。据我了解,我什至应该能够将它们作为私有继承,假设我只希望 children 具有此功能。 las,我只是收到有关受保护方法的错误消息。

我很清楚我的理解存在一些重大缺陷,但我一直在竭尽全力寻找解释,但没有成功。我真的可以对这里发生的事情使用一些建设性的见解,

谢谢,

#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 上编译它。

If you un-comment the inheritance in the Main class, the code compiles, but new each ctor/dtor is called twice, first in ascending order order and then descending order. I've been unable to reason why this would occur, but it doesn't seem correct. Every explanation of inheritance I have ever seen is vague and doesn't explain why this would need to happen.

您打了三个电话 new。然后你构造一个Main,这需要构造一个A,一个B,一个C。由于 Main 的实例是 一个 A、一个 B 和一个 C,因此必须调用这三个构造函数构建这三种类型的有效实例。

I would think that if I un-comment the "protected:" keywords, proceeding the methods in the base classes, I should be able to call them from the inherited classes.

当然可以,但不是在甚至不是派生类型的 class 的任意实例上!你有:

mA->func();

这是 class Main 的成员函数中的一个,但操作的不是 class Main 的实例。 class Main 作为 class A 的实例对自身具有特殊访问权——它的内部接口可以使用自身的 protected 函数作为 class A,仅此而已。