Specializing new

Specializing new

本文关键字:new Specializing      更新时间:2023-10-16

我想在c++中实现我自己的new版本,它接受一个分配器。我可以这样做:

template <class T>
void *operator new(std::size_t size, project::specialized_allocator<T> &a) {
  return a.allocate(size);
}

我可以使用这个分配器:

project::specialized_allocator<int> A;
int *i = new (A) int;

但是,我也可以调用:

int *i = new (nullptr) int;

Clang不会抱怨,而是编译代码。我不确定这应该做什么& &;为什么它没有因为类型错误而编译失败。nullptr不是project::specialized_allocator<T> &

我也有类似的奇怪:

int *i = new (i) int;

这是怎么回事?为什么这些例子没有失败的类型检查?

存在一个placement new操作符,它的第二个参数是void*std:nothrow_t

第一个用于在现有内存地址上分配对象。这就是为什么new (nullptr)new (i)可以编译,因为它们都可以转换为void*

第二个是告诉标准分配返回NULL指针,而不是在分配失败时抛出std::bad_alloc异常。

你可以定义你的其他参数,但你必须确保你传递的任何参数都可以转换为你的参数类型,而不是void*std::nothrow_t,否则将调用标准操作符而不是你的自定义操作符。

您使用的语法称为放置新,并且new的参数应该是一个指针。放置new实际上并没有分配任何东西;它只是在你指定的位置构造一个对象。

当你写new (nullptr)时,你告诉它在地址0处构造一个对象,而new (i)是在一个未初始化的指针的地址上构造它。这两种方法都会在运行时导致未定义的行为,因为它们涉及对null和未初始化指针的解引用。