【问题标题】:"placement new" advantage scenarios [duplicate]“安置新”优势场景[重复]
【发布时间】:2014-11-01 07:47:29
【问题描述】:

我有两种使用 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-1 相比,CASE-2 有用的场景。提前致谢。

【问题讨论】:

  • 我不得不承认我不知道 case 2 的语法。我不知道你可以像这样创建一个新的 yy 实例!有人可以确认这是否编译吗?
  • 它编译老兄..你可以编译它。
  • 您需要在放置新位置之前显式调用 dtor。重用内存时不会自动调用析构函数
  • 您只在调用new yy() 时分配了内存。之后您没有分配更多内存。放置 new 用于构造对象是内存中的特定位置(必须在之前分配)。它可以被视为一种显式调用构造函数的方式。它不调用任何析构函数。

标签: c++ new-operator


【解决方案1】:

案例1之前,您正在构造一个yy 对象(这也意味着调用xx 的基类构造函数)。在 case 1 中,除了复制指针之外,您没有构建任何东西。这不是浅拷贝,而是简单的指针拷贝。

案例 2 中,您正在使用 placement new operator 构造第二个对象 yy(还将调用基本构造函数 xx)但您 分配内存,也不调用前一个对象的析构函数,而是替换前一个元素所在的内存内容。您的代码仅泄漏一次内存,因为前一个对象不再可用,但后者是(并且内存尚未释放)。当然,如果对象还管理资源并且这些资源需要清理,因为在第二种情况下您没有调用析构函数,那将是一个问题。

new 的位置在特定情况下很有用,例如嵌入式编程,在这种情况下,您通常有一个固定地址并且需要在该确切位置构造对象(这可能有几个原因,RT 系统也不赞成动态内存分配由于可预测性和时间原因)。无论如何,在正常情况下,通常不鼓励使用它,因为它承担着必须检查分配的内存是否足够大以容纳对象、潜在对齐和其他内容的负担。非必要请勿使用。

【讨论】:

  • 替换 new 的一个可能的好方案是 object pool,您不想重新分配内存,而是在现有的情况下调用 ctor/dtor,+1 以获得好的答案
【解决方案2】:

情况 2 是应该避免的。仅在绝对必要的情况下使用(特殊限制、嵌入式软件等)

问题是你覆盖了对象,但你没有正确地结束它的生命。因此,在进行这样的放置 new 之前,您必须显式调用对象的析构函数。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-07
    • 1970-01-01
    • 2017-05-04
    • 1970-01-01
    相关资源
    最近更新 更多