在C++中实现placement new的正确方式

5
我已经按照以下方式实现了放置新内容:

我已经这样实现了放置新内容:

inline void* operator new (std::size_t n, void* ptr) {return ptr;};

我使用的环境没有标准库,所以我需要使用放置 new(placement new)。使用此放置 new 操作符的语法应如下所示:

::new (pointer) int(); 

我为什么需要size呢?我的std::size_t是无符号整数。我这样做的原因是因为没有动态内存分配,我从一个池中获取所有指针。


3
因为标准规定函数应该长成那个样子。 - StoryTeller - Unslander Monica
1
因为C++标准要求operator new()operator new[]()的所有重载都接受一个std::size_t作为第一个参数(并将传递正在构造的任何内容的大小)。放置new只是相应的operator new()operator new[]()的重载。推理是,可能需要分配内存的任何此类函数都需要知道大小。没有什么可以阻止您重载的版本忽略大小参数。 - Peter
1
inline void* operator new(std::size_t n, void* ptr) {return ptr;}; 是我实现的新操作符。编译器给了我一个错误:error: ‘operator new’ takes type ‘size_t’ (‘unsigned int’) as first parameter [-fpermissive]。 - Gustavo
@Gustavo - 我觉得你的设置很奇怪。你说你没有头文件 <new>(很奇怪,因为它是符合标准的独立环境的最低要求),但你有 <cstddef> 并且可以使用 std::size_t - StoryTeller - Unslander Monica
1
标准还指出,运算符 new(size_t,void *)的放置形式是不可替换的,也许你应该声明一个重载,例如 operator new(size_t,void *,my_type),并使用这个表达式:new(ptr, my_type{}) int()。如果你不这样做,并且将你的代码链接到其他可能会产生意外结果的代码中。 - Oliv
显示剩余4条评论
1个回答

6

我原本只是打算发表一条评论,但在 melpomene 建议这是一个答案之后...

C++ 标准要求所有重载的 operator new()operator new[]() 都需要接受一个 std::size_t 作为第一个参数(实现将确保正在构建的任何东西的大小通过该参数传递)。

放置 new(placement new)只是相应的 operator new()operator new[]() 的重载。因此,它必须采用那种形式。

推理是,可能需要分配内存的任何此类重载函数都需要访问大小信息。

没有什么可以阻止您的重载版本忽略大小参数——这可能解释了为什么标准不费心允许在没有该参数的情况下重载 operator new()operator new[]()


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接