C++不必要的破坏
有人可以解释为什么当c
完成构造时,b
(c的成员)的析构函数被调用,而d
被析构 - 正如预期的那样 - c
的析构函数何时被调用?
#include <iostream>
using namespace std;
class A
{
public:
int a, b;
};
class B
{
public:
A* array[10];
B()
{
for(int i = 0 ; i < 10 ; i++)
array[i] = new A();
}
~B()
{
for(int i = 0 ; i < 10 ; i++)
delete array[i];
}
};
class C
{
public:
B b;
B* d;
C()
{
b = B();
}
~C()
{
delete d;
}
};
int main()
{
B b = B();
C c = C();
cout << "Ashlamish" << endl;
system("pause");
return 0;
}
Can somebody explain why when c
finishes construction, the destructor of b
(member of c) is called, while d
is destructed - as expected - when c
's destructor is called ?
#include <iostream>
using namespace std;
class A
{
public:
int a, b;
};
class B
{
public:
A* array[10];
B()
{
for(int i = 0 ; i < 10 ; i++)
array[i] = new A();
}
~B()
{
for(int i = 0 ; i < 10 ; i++)
delete array[i];
}
};
class C
{
public:
B b;
B* d;
C()
{
b = B();
}
~C()
{
delete d;
}
};
int main()
{
B b = B();
C c = C();
cout << "Ashlamish" << endl;
system("pause");
return 0;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
在
b = B()
中,您构建了类 B 的一个新的临时实例,将一个副本分配给 b,然后对该临时实例进行解构。In
b = B()
you're constucting a new temporarty instance of class B, assigning a copy to b, then the temporary instance is descructed.因为在 C 的构造函数中,您在
c = B();
行中创建了一个临时 B 对象,并且当赋值完成时,该临时对象将被销毁。Because in the constructor of C, you are creating a temporary B object in the line
c = B();
and when the assignment is complete, that temporary object is being destroyed.我认为你想像这样声明 c :
这将构造一个名为 c 的对象,该对象将在作用域退出时被破坏。
另一方面,你拥有什么;
将构造一个 C 类型的匿名对象,用它复制构造 c 并立即销毁该匿名对象。 c 仍将在作用域结束时被破坏。
I think you want to declare c like this:
This will construct an object named c which will be destructed on scope exit.
On the other hand, what you have;
will construct an anonymous object of type C, copy construct c with it and immediately destruct the anonymous object. c will still be destructed at the end of the scope.
在 C 的构造函数中,它
的作用是:
要修复此问题,请在 C 的构造函数中使用初始化列表,如下所示:
或只是将构造函数留空,这样它将使用默认构造函数。
In the constructor of C you have
what this does is:
To fix this use initialization list in the constructor of C like this:
or just leave the constructor empty, that way it will use the default constructor.
C
构造函数中的b = B();
行实例化了B
类型的新对象,并使用B
的复制构造函数来复制C::b
中的此类对象。当
C
构造函数返回时,b
不会被销毁,但用于调用b
的B
临时对象复制构造函数是。您可以删除此类指令,以避免实例化
B
临时对象,在这种情况下,b 将仅使用默认构造函数构造。The line
b = B();
inC
constructor instantiates a new object of typeB
, and usesB
's copy constructor to copy such object inC::b
.When
C
constructor returnsb
doesn't get destroyed, but theB
temporary object used to callb
's copy constructor is.You could just remove such instruction in order to avoid instantiation of a
B
temporary, in this case b will just be constructed using the default constructor.临时 B 的析构函数被调用 (
b = B();
),而不是成员b
的析构函数。这行完全可以删除,因为b
已经在隐式初始化列表中默认构造destructor of temporary B is called (
b = B();
), not of memberb
. this line can be removed at all becauseb
is already default constructed in implicit initialization list你在这里犯下了大罪 - 不遵守3规则。
你的 B 需要一个析构函数,但没有实现复制和赋值。
然后你继续通过实际做作业来复合错误。
您还可以继续删除未初始化的指针。 (如果 d 为 NULL 就可以了,但没有理由为什么它应该是 NULL)。
您还需要实现复制构造,特别是当您的编译器很可能选择将其用于上述构造时,尽管它实际上可能不会这样做。
You have committed here a cardinal sin - not obeying the rule of 3.
Your B needs a destructor but does not implement copying and assignment.
You then go ahead and compound the error by actually doing an assignment.
You also go on to delete an uninitialised pointer. (It would be fine if d were NULL but there is no reason why it should be).
You also need to implement copy-construction, especially as your compiler may well choose to use it for the above constructs, although it probably won't actually do so.