为什么 std::make_shared 无法编译带有已删除运算符 new 的类型?
Why doesn't std::make_shared fail to compile for type with deleted operator new?
>我正在尝试编写堆禁止类型,即在堆分配的内存上不可构造的类型。通过删除运算符 new 和放置 new,我认为我会实现这一目标。但是使用std::make_shared
创建共享指针仍然可以编译。
为什么删除新运算符时std::make_shared<A>()
不会编译失败?
#include <memory>
class A {
public:
void* operator new(size_t) = delete;
void* operator new(size_t, void*) = delete;
void* operator new [] (size_t) = delete;
};
// Regular new fails
A* a1 = new A();
// Placement new fails
void* pv = std::malloc(sizeof(A));
A* a2 = new (pv) A();
// make_shared works
std::shared_ptr<A> a3 = std::make_shared<A>();
std::make_shared
是根据::new (pv) T(std::forward<Args>(args)...)
指定的。
[util.smartptr.shared.create]
2效果:分配适合 T 型对象的内存 并通过放置在该内存中构造一个对象 新表达
::new (pv) T(std::forward<Args>(args)...)
.这 模板allocate_shared使用 A 的副本来分配内存。如果 引发异常,函数不起作用。
分配的内存通常用于控制块,而不是直接用于new T
。然后通过放置 new 构造对象,但新表达式完全有资格使用全局放置operator new
,而不是任何特定于类的放置。
[新品]
9 如果新表达式以一元运算符开头
::
则 分配函数的名称在全局范围内查找。 否则,如果分配的类型是类类型 T 或其数组, 分配函数的名称在 T 的作用域中查找。如果这个 查找找不到名称,或者分配的类型不是类 类型,则在全局范围内查找分配函数的名称。
这两种用法将完全绕过自定义删除的运算符。
相关文章:
- 编译"运算符删除"时C++编译器如何工作?
- 删除 x 与 ::运算符删除 (x)
- 未找到匹配的运算符删除;如果初始化引发异常,内存将不会被释放
- 为什么在运算符删除中不调用析构函数?
- 如何在 C++ 中使用删除运算符删除单个数据
- C++对自动(堆栈)指针使用运算符删除
- C++运算符删除覆盖并不总是使用
- 带大小参数和不带大小参数的"运算符删除":当两者都可用时,选择哪一个?
- C++ 运算符删除重载对派生类不起作用
- 无法覆盖C++中纯抽象类中的运算符删除/新建
- 对运算符删除覆盖的工作方式感到困惑
- C++/析构函数-运算符删除
- C++can运算符删除失败,如果不是原因
- 如果我写一个新的展示位置?我应该如何编写普通运算符删除
- 删除与运算符删除(和无效指针)
- 使用单个删除运算符删除多个指针
- 如何实现 C "classes" 的 C++11 冒名顶替者的运算符删除?
- shared_ptr-运算符删除中的访问冲突
- 使用delete运算符删除结构中的元素
- 内存管理 - 目标 C++ 运算符删除