2

我遇到了一个例子:

#include <iostream>
#include <stdexcept>

using namespace std;

class A{
public:
    A():m_n(m_object_id++){}
    ~A(){cout << m_n;}
private:
    const int m_n;
    static int m_object_id;
};

int A::m_object_id=0;


int main()
{
    A * const p = new A[3];
    A * const q = reinterpret_cast<A * const> (new char[3*sizeof(A)]);
    new (q) A;
    new (q+1)A;
    q->~A();
    q[1].~A();
    delete [] reinterpret_cast<char *>(q); // -> here
    delete[] p;
    cout << endl;

    return 0;
}

输出: 34210

有人可以解释一下delete [] reinterpret_cast<char *>(q); // -> here,它在做什么并产生任何输出吗?

编辑

我的问题delete [] reinterpret_cast<char *>(q);不是打电话~A(){cout << m_n;}delete[] p;为什么会这样?

4

4 回答 4

3

delete []为数组的每个元素调用析构函数,然后释放相关的内存。delete在指向数组的指针上只会调用第一个元素的析构函数,然后释放所有关联的内存。

delete []使用时始终使用new [..].

要调用的析构函数由传递给deleteor的指针的类型决定delete []。在下面的示例中:

A *object1 = new A();
B *object2 = new B();

delete (B*) object1;
delete (A*) object2;

将(可能)导致所有地狱都崩溃,因为~B()正在被调用,A反之亦然。

void *object = new A();
delete object;

不调用~A(),因为它不知道object指向 的实例A,而

void *object = new A();
delete reinterpret_cast<A*>(object);

~A()在释放相关内存之前正确调用。

于 2013-06-28T01:51:09.573 回答
2

q使用 的内存进行初始化new char[3*sizeof(A)],但被视为 的数组A。然后使用该内存对该数组的前两个元素执行放置new

A * const q = reinterpret_cast<A * const> (new char[3*sizeof(A)]);
new (q) A;
new (q+1)A;

在构造元素上显式调用析构函数后,q被强制转换回 a char *,并使用 删除内存delete []。强制转换的目的是确保将其应用于使用指向 whichdelete[]的调用创建的相同类型的对象。new[]q

q->~A();
q[1].~A();
delete [] reinterpret_cast<char *>(q); // -> here

用 分配的对象集合new[]必须用 删除delete[]。这是因为delete[]将指针视为数组分配,并适当地破坏每个数组元素。

于 2013-06-28T01:56:11.610 回答
1

new char[3*sizeof(A)]说“为我分配一些足够大的空间用于 3 As,但将该空间视为 char 数组/字符串。”

reinterpret_cast<A * const>说把你刚刚分配的内存块当作一个字符串,现在把它当作一个 As 数组。

delete [] reinterpret_cast<char *>(q);说现在把你现在认为的那个内存块作为一个 As 数组,然后开始再次把它看作一个数组 char,因为它是如何分配的,所以这就是它必须被删除的方式。(即,delete[] 将在该数组中的每个 char 上调用 char dtor,而不是调用 A dtor)

不要在真正的代码中做任何事情!

于 2013-06-28T01:54:52.240 回答
0

p 被分配为 A 类的简单数组,然后被删除。q 更复杂,因为它被分配为原始内存,然后使用placement new 在该原始内存中创建A 的两个元素。这两个元素被单独删除,原始内存被您询问的语句删除。

于 2013-06-28T01:57:33.400 回答