如果我写一个新的展示位置?我应该如何编写普通运算符删除
If I write a placement new?How should I write normal operator delete?
在"有效C++"中 第 52 项:写放置 如果写新放置,请删除。
迈耶斯说,对于Widget *pw = new (std::cerr) Widget;
,将调用放置新位置。但是,如果放置 new 没有抛出异常,并且我们会在客户端代码中删除:delete pw;
.然后,此delete
将仅调用正常删除,而不调用放置删除。
然后,Meyers 得出的结论是,您必须提供正常的运算符删除。那么,这个普通的运算符删除应该是什么样的呢?我认为这个普通运算符删除的内部应该类似于放置删除。
但是如果我使用普通运算符 new 而不是放置 new 来创建对象Widget *pw = new Widget;
,然后使用delete pw
,那么它也会调用我为放置编写的普通运算符 delete new 。但这似乎不对。
像这样:
struct Widget {
Widget() { throw std::runtime_error(""); }
// custom placement new
static void* operator new(std::size_t sz, const std::string& msg) {
std::cout << "custom placement new called, msg = " << msg << 'n';
return ::operator new(sz);
}
// custom placement delete
static void operator delete(void* ptr, const std::string& msg)
{
std::cout << "custom placement delete called, msg = " << msg << 'n';
::operator delete(ptr);
}
};
int main()
{
try {
Widget* p1 = new ("widget") Widget;
}
catch(const std::exception& e) {
std::cout << e.what() << 'n';
}
}
您不需要编写类似于放置删除的普通运算符删除。
相反,当您要删除由放置 new 创建的对象时,您必须通过 Widget::delete(pw, std::cerr)
调用放置删除。你不应该直接调用delete pw
,如果你这样做,编译器会抱怨。在 vs2013 中,编译器将输出
无法删除指向此类型对象的指针;该类没有用于"运算符删除"的非放置重载
因此,无需担心在正常运算符删除中的位置删除。
相关文章:
- 我应该使用什么来代替void作为变体中的替代类型之一
- boost::asio::steady_timer()与sleep()我应该使用哪一个
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 我是C++编程的新手,这些代码之间有什么区别,我应该使用哪一个
- 我应该删除矢量<short>吗?
- 我应该如何修改此代码以使用给定字符串中的字母打印菱形图案
- 我应该在锁定TBitmap画布后解锁它吗
- 为什么我应该在异常处理中使用std::cerr而不是std::cout
- 我应该避免多重实现继承吗
- 为了方便起见,我应该避免公开私有字段变量吗
- 我收到同义重复编译器错误。我应该如何修复"类型"X"的参数与类型"X"的参数不兼容?
- 违反const正确性:我应该现实地期待什么问题
- 我应该如何表示我拥有的连续元素序列?
- 我应该将除 .cpp 以外的其他文件添加到 git 中吗?
- 我应该如何从 stdin C++ 中读取可变长度的格式字符串?
- 我有一个对象,它将在整个程序的持续时间内实例化,但一个类成员不会,我应该动态分配它吗?
- 我应该如何捕捉out_of_range异常?
- 我应该在服务模板中的什么位置添加自己的代码?
- 如果我写一个新的展示位置?我应该如何编写普通运算符删除
- 我应该如何存储和跟踪统一/属性位置