对象初始化期间的析构函数调用?

时间:2012-01-11 18:05:15

标签: c++

鉴于下面的代码,为什么我会得到关于A的析构函数是私有的错误?显然它是私有的,但我不明白为什么以这种方式初始化B的对象实例会导致调用A的析构函数。

对于任何拼写错误道歉,我正在从非联网系统重新创建内存中的代码而没有编译器。

class A
{
    public:
        A(int val) : x(val) {}

    private:
        int x;
        ~A() {}
};

class B
{
    public:
        B() : aInstance() {}

    private:
        A aInstance;
};

int main()
{
    B b;
}

6 个答案:

答案 0 :(得分:5)

初始化本身不涉及使用dtor,但B的实例在main结束时被销毁。 B包含A,因此当B被销毁时,A也必须被销毁 - 但A的dtor不是可用,因此无法生成代码。

答案 1 :(得分:2)

由于B类包含A类的实例(作为私有字段aInstance),因此必须在销毁B的实例时销毁它。

这正是你main内发生的事情。当B b;在堆栈上分配和创建时,它会在函数结束时超出范围,必须被销毁,就像C ++中的每个本地对象一样。

答案 2 :(得分:0)

在main()结束时,当B超出范围时,B应该如何解除分配A类成员?

它不能,因为你声明了析构函数是私有的。

答案 3 :(得分:0)

原因是AB的成员。类型B的默认生成构造函数必须是规则调用每个字段的析构函数。因此,对A析构函数有一个隐式调用,它没有访问权限而你得到错误

答案 4 :(得分:0)

我怀疑是否在构造函数中调用了A的析构函数。当A超出main的范围时(程序终止时),可能会调用b的析构函数。

答案 5 :(得分:0)

实际上B需要访问析构函数而不是main()。

如果你让B成为A的朋友,它会起作用。如果你让main()成为A的朋友,它将无法编译。

因为A的实例被声明为“自动”,即它是一个类成员,它的删除不会发生在B的析构函数中,但会在B的破坏期间发生。但是,这被认为属于B作为一个班级的访问范围。