如何正确销毁使用 placement new 构造的派生对象
How do I correctly destruct a derived object that was constructed using placement new
假设我们有一个具有这种 class 继承的 C++ 程序:
class A {
public:
virtual ~A() {/* ... */}
};
class B : public A {
public:
virtual ~B() {/* ... */}
};
class C : public A {
public:
virtual ~C() {/* ... */}
};
此外,还有专门的内存限制,要求 B 和 C 必须始终分配在 RAM 的特殊区域(例如,物理 SRAM 的保留区域,以保证比普通 SDRAM 更快的响应时间),因此我们必须永远不要从通用堆中分配 B 或 C 的实例。所以我们可能有这样的东西:
A * ptr;
if(condition) {
ptr = specialized_allocator(sizeof(B));
new(ptr) B;
} else {
ptr = specialized_allocator(sizeof(C));
new(ptr) C;
}
/* Do something, which persists beyond the scope
of the function where allocation occurred... */
ptr->~A();
specialized_deallocator(ptr);
在这种情况下,派生的 class 析构函数的完整链是否会被正确调用,还是最终只会调用顶级 A 析构函数?
运行 这个可能有点帮助:
#include <iostream>
class A {
public:
virtual ~A() { std::cout << "A\n"; }
};
class B : public A {
public:
virtual ~B() { std::cout << "B\n"; }
};
class C : public A {
public:
virtual ~C() { std::cout << "C\n"; }
};
int main()
{
A* ptr = new C(); // or A* ptr = new B()
// ...
ptr->~A();
}
假设我们有一个具有这种 class 继承的 C++ 程序:
class A {
public:
virtual ~A() {/* ... */}
};
class B : public A {
public:
virtual ~B() {/* ... */}
};
class C : public A {
public:
virtual ~C() {/* ... */}
};
此外,还有专门的内存限制,要求 B 和 C 必须始终分配在 RAM 的特殊区域(例如,物理 SRAM 的保留区域,以保证比普通 SDRAM 更快的响应时间),因此我们必须永远不要从通用堆中分配 B 或 C 的实例。所以我们可能有这样的东西:
A * ptr;
if(condition) {
ptr = specialized_allocator(sizeof(B));
new(ptr) B;
} else {
ptr = specialized_allocator(sizeof(C));
new(ptr) C;
}
/* Do something, which persists beyond the scope
of the function where allocation occurred... */
ptr->~A();
specialized_deallocator(ptr);
在这种情况下,派生的 class 析构函数的完整链是否会被正确调用,还是最终只会调用顶级 A 析构函数?
运行 这个可能有点帮助:
#include <iostream>
class A {
public:
virtual ~A() { std::cout << "A\n"; }
};
class B : public A {
public:
virtual ~B() { std::cout << "B\n"; }
};
class C : public A {
public:
virtual ~C() { std::cout << "C\n"; }
};
int main()
{
A* ptr = new C(); // or A* ptr = new B()
// ...
ptr->~A();
}