鉴于下面的代码,为什么我会得到关于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;
}
答案 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)
原因是A
是B
的成员。类型B
的默认生成构造函数必须是规则调用每个字段的析构函数。因此,对A
析构函数有一个隐式调用,它没有访问权限而你得到错误
答案 4 :(得分:0)
我怀疑是否在构造函数中调用了A
的析构函数。当A
超出main的范围时(程序终止时),可能会调用b
的析构函数。
答案 5 :(得分:0)
实际上B需要访问析构函数而不是main()。
如果你让B成为A的朋友,它会起作用。如果你让main()
成为A的朋友,它将无法编译。
因为A的实例被声明为“自动”,即它是一个类成员,它的删除不会发生在B的析构函数中,但会在B的破坏期间发生。但是,这被认为属于B作为一个班级的访问范围。