C++中“delete this”和“this->~Obj”之间的区别

difference between `delete this` and `this->~Obj` in C++

提问人:ln vv 提问时间:2/13/2023 更新时间:2/13/2023 访问量:119

问:

当我编写演示字符串类时,在复制分配函数中,我尝试在复制之前通过“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) 已中止(核心转储)

c++ 内存管理 赋值运算符 delete-operator 双重释放

评论

0赞 ALX23z 2/13/2023
delete thiscalls 和 .当对象通过 创建时,可以通过 删除对象。在手动调用析构函数时,要与放置 new 一起使用。this->~Obj();free(this)deletenewthis->~Obj();
0赞 Botje 2/13/2023
delete this运行析构函数释放给定对象的任何内存。只需编写一个单独的“dealloc”函数并调用它,而不是使用析构函数来玩弄。
0赞 Retired Ninja 2/13/2023
C++中是否允许“删除此内容”?值得一读。
1赞 HolyBlackCat 2/13/2023
@ALX23z 不是 ,而是 .free(this);operator delete(this);
0赞 Karl Knechtel 2/13/2023
另请阅读: 什么是三法则?

答:

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()xUTTU
1赞 user10 2/13/2023 #2

你已经执行了,但这只是一个问题。在你打电话之后,实际上是.但生存期已经结束,因此任何调用都可能导致未定义的行为。所以不属于也不属于你的分配运营商。delete thisthis->~Str()delete this_size = s._sizethis->_size = s._sizethisthisdelete thisthis->~Str()

评论

1赞 user10 2/13/2023
@Retired忍者好点。