我有两种使用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;
}
在CASE-1中,我只是将y1内存分配给y2而不破坏y1(浅拷贝)。这里不会调用构造函数。
在CASE-2中,我将y1内存分配给y3到破坏y1的地址。这里将调用y3的构造函数。但是没有调用y1的析构函数。根据我的理解,应用程序必须在将来的代码中使用y1和y2时采取空值检查的预防措施。
所以基本上我想了解CASE-2与CASE-1相比有用的场景。提前谢谢。
答案 0 :(得分:2)
在案例1 之前,您正在构建一个yy
对象(这也意味着调用xx
的基类构造函数)。在 case 1 中,除了复制指针之外,你不构建任何东西。这是 NOT 浅拷贝,但是是一个简单的指针拷贝。
在案例2 中,您使用placement new
operator构建第二个对象yy
(并且还将调用基础构造函数xx
)但是你 NOT 分配内存,也没有调用前一个对象的析构函数,而是替换前一个元素所在的内存内容。您的代码只泄漏一次内存,因为上一个对象不再可用,但后者是(并且内存未被释放)。当然,如果对象也管理资源并且需要清理那些资源,那么因为你在第二种情况下没有调用析构函数会产生问题。
展示位置new
在嵌入式编程等特殊情况下非常有用,在这种情况下,您经常拥有固定的地址,并且您需要在该位置构建对象(可能有多种原因,也就是RT系统在动态时皱眉由于可预测性和时间原因导致的内存分配)。无论如何,在正常情况下,它的使用通常是不鼓励的,因为它承担了必须检查分配的内存是否足够大以用于对象,潜在对齐和其他东西的负担。如果你不必,不要使用它。
答案 1 :(得分:0)
案例2应该避免。仅在绝对必要的情况下使用(特殊约束,嵌入式软件等)
问题是你覆盖了对象,但是没有正确地结束它的生命。所以在进行这样的放置之前,你必须明确地调用对象的析构函数。