在 C++ 中分配时,我们分配的对象是否会被破坏?
下面的代码片段是否泄漏?如果不是,那么 foobar() 中构造的两个对象在哪里被破坏?
class B
{
int* mpI;
public:
B() { mpI = new int; }
~B() { delete mpI; }
};
void foobar()
{
B b;
b = B(); // causes construction
b = B(); // causes construction
}
Does the following code fragment leak? If not, where do the two objects which are constructed in foobar() get destructed?
class B
{
int* mpI;
public:
B() { mpI = new int; }
~B() { delete mpI; }
};
void foobar()
{
B b;
b = B(); // causes construction
b = B(); // causes construction
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
默认的复制赋值运算符执行按成员复制。
因此,对于您的情况:
请参阅《Effective C++,第二版》中的第 11 条了解更多详细信息。
The default copy assignment operator does a member-wise copy.
So in your case:
See Item 11 in Effective C++, 2nd Edition for more details.
是的,这确实会泄漏。编译器会自动提供一个额外的方法,因为您还没有定义它。它生成的代码与此等效:
这意味着会发生以下情况:
这显然很糟糕。如果您违反三法则。您已经定义了一个重要的析构函数和一个复制构造函数。不过,您还没有定义副本分配。三原则是,如果您定义了上述任何一个,您应该始终定义所有三个。
相反,请执行以下操作:
Yes, this does leak. The compiler automatically provides an extra method because you have not defined it. The code it generates is equivalent to this:
This means that the following stuff happens:
This is obviously bad. This is likely to occur in any instance that you violate the rule of three. You have defined a non-trivial destructor and also a copy constructor. You have not defined a copy assignment, though. The rule of three is that if you define any of the above, you should always define all three.
Instead, do the following:
您正在构建三个对象,所有对象都将被破坏。问题是默认的复制赋值运算符将执行浅复制。这意味着指针被复制,从而导致它被多次删除。这会导致未定义的行为。
这就是3 规则背后的原因。您有一个析构函数,但没有其他两个。您需要实现复制构造函数和复制赋值运算符,它们都应该执行深层复制。这意味着分配一个新的 int,复制该值。
You're constructing three objects, and all will be destructed. The problem is that the default copy-assignment operator will do a shallow copy. That means the pointer is copied over, which causes it be be deleted more than once. This causes undefined behavior.
This is the reason behind the rule of 3. You have a destructor but not the other two. You need to implement a copy constructor and copy assignment operator, both of which should do a deep copy. This means allocating a new int, copying the value over.
正如多次指出的,你违反了三法则。只是为了添加链接,在堆栈溢出上对此进行了很好的讨论:什么是三法则?
As pointed out several times, you've violated the rule of three. Just to add to the links, there is a great discussion of this on stack overflow: What is The Rule of Three?
只是为了提供一种不同的方法来解决我最初发布的代码的问题,我想我可以将指针保留在 B 类中,但去掉内存管理。然后我不需要自定义析构函数,因此我不会违反 3 规则...
Just to offer a different approach to solving the problems of the code I originally posted, I think I could keep the pointer in class B, but take the memory mangement out. Then I need no custom destructor, and so I don't violate the rule of 3...