我有两个使用new运算符的内存分配案例。
class xx{
public: int x;
xx(){}
~xx(){}
};
class yy : public xx {
public: int y;
yy(){}
~yy(){}
};
int main(int argc, char *argv[])
{
yy *y1 = new yy(); //y1 constructor is called
//CASE-1
yy *y2 = y1;
//CASE-2
yy *y3 = new (y1) yy();
return 0;
}在第一种情况下,我只是将y1内存分配给y2,而不破坏y1(浅拷贝)。这里不会调用构造函数。
在第二种情况下,我将y1内存分配给销毁y1的地址y3。这里将调用y3的构造函数。但未调用y1的析构函数。根据我的理解,在将来的代码中使用y1和y2时,应用程序必须注意空值检查。
因此,基本上我想了解CASE-2与CASE-1相比是有用的场景。提前谢谢。
发布于 2014-09-08 14:22:13
在第一种情况之前,您将构造一个yy对象(这也意味着要调用xx的基类构造函数)。在第一种情况下,你没有构造任何东西,只是复制指针。也就是说,不是一个浅拷贝,而是一个简单的指针拷贝。
在第二种情况下,您将使用placement new operator构造第二个对象yy (也将调用基构造器xx ),但是您将,而不是分配内存,也不是调用前一个对象的析构函数,而是替换前一个元素所在的内存内容。您的代码只泄漏了一次内存,因为前一个对象不再可用,而后者可用(并且内存尚未释放)。当然,如果对象也管理资源,并且这些资源需要清理,因为在第二种情况下没有调用析构函数,这将是一个问题。
放置new在像嵌入式编程这样的特定环境中很有用,在这种情况下,您通常有一个固定的地址,并且需要在该位置构造对象(这可能有几个原因,RT系统也不喜欢动态内存分配,因为可预测性和计时原因)。无论如何,在正常情况下,通常不鼓励使用它,因为它需要检查分配的内存是否足以容纳对象、潜在对齐和其他东西。如果没有必要,请不要使用它。
发布于 2014-09-08 14:26:36
情况2是应该避免的事情。仅在绝对必要的情况下使用(特殊约束、嵌入式软件等)
问题是您覆盖了对象,但没有正确地结束它的生命周期。所以在做这样的放置之前,你必须显式地调用对象的析构函数。
https://stackoverflow.com/questions/25718361
复制相似问题