我在阅读放置新操作符时发现了以下代码。
#include <iostream>
using namespace std;
class MyClass {
public:
// Placement new operator
void* operator new (size_t sz, void* v) {
cout << "Placement new invoked" << endl;
return v;
}
~MyClass() {
// Cleanup
}
};
int main()
{
// Create a buffer to store the object
int buffer[16];
cout << "Starting address of my buffer = " << &buffer << endl;
// Create the object. Use placement new
MyClass* obj = new (buffer) MyClass();
cout << "Location of my object = " << obj << endl;
// Don't delete object created with placement delete
// Call the destructor explicitly
obj->~MyClass();
}
我几乎没有与使用placement new:
创建的删除对象相关的问题答案 0 :(得分:0)
什么是清理代码需要在析构函数中编写以释放缓冲内存中占用obj的内存
析构函数应该执行任何析构函数的操作:清理对象管理的所有资源。在这种情况下,它不管理任何资源,因此不需要做任何事情。
根据如何分配对象本身的存储空间,它不应该做任何特殊操作。在需要时,管理该存储是自定义new
和delete
运营商的工作。
不需要定义展示位置删除
没有。 Placement-new用于构建您自己管理的存储中的对象,您自己负责释放该存储。在这种情况下,存储是自动的,因此当函数退出时它会自动释放。
就像placement-new的分配器什么都不做(只是将提供的指针返回到预先分配的存储)一样,相应的deallocator什么都不做;所以它不存在。你只需要在自己处理存储之前直接调用它的析构函数来销毁对象。
答案 1 :(得分:0)
常规new
会做两件事:
展示位置new
表示您管理其中一个,另一个像以前一样进行管理。
反之为delete
,常规delete
执行以下操作:
请注意,出于显而易见的原因,它们以相反的顺序完成。您无法释放包含有关需要清理的内容的信息的内存,即使您已完成使用该内存。而在构造中,你需要先掌握记忆。
在你所谓的贴片删除中,但实际上与贴片新位置相反,你需要执行破坏的第一步而不是第二步。因此,您调用对象的析构函数,然后您可以释放它使用的内存/将其用于其他内容。
使用placement new的最常见示例是std::vector
的实现,它需要一个连续的缓冲区用于其数据,并且允许您提前预订(如果不这样做,它可能会执行此操作)您)。该部分分配内存但不构造其中的对象。因此,当它们稍后构建时,将使用placement new。
答案 2 :(得分:0)
首先要问的是:你想做什么?如果你
在类中定义一个新的贴装操作符,然后就是
只有在编写new
MyClass
时才能找到的operator new;你必须总是指定额外的参数。并在
几乎在每个定义特定类operator
new
的情况下,您还应该定义一个特定类operator delete
;
否则将调用全局operator delete
函数
当你写delete p
时,这通常是行不通的。
如果你的目标是系统地要求分离
分配和初始化,这就是你定义的原因
一个成员运营商new,然后你可以提供一个no-op operator
delete
;如果类的构造函数可以抛出,那么你就可以了
还希望提供一个放置操作符删除,因为这是
如果新对象的构造函数退出,将调用什么
通过例外。然而,没有其他方法可以称之为。
提供新的展示位置运算符时,您必须提供
一个默认的运算符delete,它做了正确的事;什么时候
您需要为同一类型提供多个新操作员
在每个分配中以某种方式记住哪个被称为
命令在非放置运算符中分派删除。
顺便说一下,只需将缓冲区分配为局部变量 不保证足够的对齐除了 声明缓冲类型。
编辑:
只是operator
delete
函数(必须是成员)所需内容的示例:
void operator delete( void* p ) {}
void operator delete( void* p, void* ) {}