放置新的覆盖现有对象

时间:2016-09-02 08:05:45

标签: c++ placement-new

如果我要在已经在堆栈上创建的对象上放置新内容:

struct s{
s() { std::cout << "C\n";}
~s() { std::cout << "D\n";}
};

int main() {
        s s1[3];
        for(int i=0; i< 3; ++i)
                s* newS = new (&s1[i]) s();
}

我明白了:

C
C
C
C
C
C
D
D
D

所以我们没有获得前3个对象的析构函数,这样安全吗?如果我们只是覆盖堆/堆栈上分配的对象的内存,并且对象不必释放析构函数中的任何资源,那还是安全吗?

1 个答案:

答案 0 :(得分:3)

wandbox example

您的输出并非意外 - placement new不会调用存储在您正在访问的内存位置的任何潜在对象的析构函数。您需要explictly invoke the destructor占用您尝试使用的内存位置的任何对象,以便安全地使用展示位置new

struct s
{
    s()
    {
        std::cout << "C\n";
    }
    ~s()
    {
        std::cout << "D\n";
    }
};

int main()
{
    // Three 's' instances are constructed here.
    s s1[3];

    // (!) You need to explicitly destroy the existing
    // instances here.
    for(int i = 0; i < 3; ++i)
    {
        s1[i].~s();
    }

    for(int i = 0; i < 3; ++i)
    {
        // Three 's' instances are constructed here.
        s* newS = new(&s1[i]) s();
    }

    // Three 's' instances are destroyed here.
}

输出:

C
C
C
D
D
D
C
C
C
D
D
D