提问人:ln vv 提问时间:2/13/2023 更新时间:2/13/2023 访问量:119
C++中“delete this”和“this->~Obj”之间的区别
difference between `delete this` and `this->~Obj` in C++
问:
当我编写演示字符串类时,在复制分配函数中,我尝试在复制之前通过“delete this”清除自身。但它失败了。
Str &operator=(const Str &s) {
if (this != &s) { // self-assignment check
//delete this; //cannot run as I imagine
this->~Str();
_size = s._size;
_str = new char[_size + 1];
memcpy(_str, s._str, _size + 1);
}
return *this;
}
~Str() {
_size = 0;
delete[] _str;
}
Linux 告诉我
双重释放或损坏 (OUT) 已中止(核心转储)
答:
7赞
HolyBlackCat
2/13/2023
#1
delete x;
等价于 后跟 (类似于 ,但可能与它不兼容)。x->~T();
operator delete(x)
free(x)
x->~T();
是一种危险的工具。在这种情况下,它后面必须跟着 (placement-new) 来调用构造函数,否则当前对象将被视为“死”对象,并且与它的任何交互都会导致未定义的行为。new(this) T(...);
但即使你确实称 placement-new,它也会抛出。然后对象保持死机状态,调用方在尝试再次销毁已经死机的对象时获得 UB。
结论:很难正确使用,使用其他东西。x->~T();
要么编写一个与 destrutor 执行相同操作的函数,然后改为调用它。与析构函数不同,对象在调用后不会被视为已死,因此不需要 placement-new。
或者使用复制和交换成语。将作业写成:
Str &operator=(Str s) noexcept { std::swap(_str, s._str); std::swap(_size, s._size); return *this; }
这是一种通用的写作作业方式。它既可以作为复制任务,也可以作为移动任务,是异常安全的,等等。
评论
1赞
user253751
2/13/2023
我认为,最明智的用法是,如果您使用 placement-new 创建了对象。x->~T();
1赞
HolyBlackCat
2/13/2023
@user253751嗯,我只是说它不适合这个用例。
1赞
Pete Becker
2/14/2023
另一个后跟放置 new 的陷阱是,如果指向的对象的原始类型是从结果派生的类型,那么它将是一个既不是 a 也不是 a 的不可行混合体。x->~T()
x
U
T
T
U
1赞
user10
2/13/2023
#2
你已经执行了,但这只是一个问题。在你打电话之后,实际上是.但生存期已经结束,因此任何调用都可能导致未定义的行为。所以不属于也不属于你的分配运营商。delete this
this->~Str()
delete this
_size = s._size
this->_size = s._size
this
this
delete this
this->~Str()
评论
1赞
user10
2/13/2023
@Retired忍者好点。
评论
delete this
calls 和 .当对象通过 创建时,可以通过 删除对象。在手动调用析构函数时,要与放置 new 一起使用。this->~Obj();
free(this)
delete
new
this->~Obj();
delete this
运行析构函数并释放给定对象的任何内存。只需编写一个单独的“dealloc”函数并调用它,而不是使用析构函数来玩弄。free(this);
operator delete(this);