«удалить это» в конструкторе - PullRequest
26 голосов
/ 14 марта 2011

Что на самом деле происходит, когда я выполняю этот код?

class MyClass
{
    MyClass()
    {
        //do something
        delete this;   
    }
}

Ответы [ 3 ]

36 голосов
/ 14 марта 2011

Оказывается, что в данном конкретном случае код является допустимым, но вы вдали от неопределенного поведения.

Стандарт C ++ определяет понятие «времени жизни» объекта как времени, между которым его конструктор завершил работу и когда деструктор начинает работать. Он также прямо заявляет (в разделе 3.8 / 5), что

До начала жизни объекта [...] Если объект будет или имел тип класса с нетривиальным деструктором, а указатель используется в качестве операнда выражения удаления, программа имеет неопределенное поведение.

Поскольку время жизни объекта не начинается до тех пор, пока не завершится конструктор, в конструкторе указанный вами указатель this еще не начал свое время жизни, поэтому попытка delete в этом случае абсолютно безопасна. Однако, если вы напишите деструктор для класса, вы тут же столкнетесь с неопределенным поведением.

Кроме того, если вы измените конструктор, чтобы попытаться сослаться на любой из элементов данных класса после удаления объекта, вы получите неопределенное поведение. Если объект был размещен в стеке, вы получите неопределенное поведение. Если объект был статичным, вы получите неопределенное поведение. Если объект был выделен с использованием new, то указатель, на который клиент вернется, будет недействительным, и его использование приведет к неопределенному поведению. В общем, не пытайтесь делать это!

0 голосов
/ 25 августа 2018

Первое, что я хочу понять, это: ПОЧЕМУ Вы хотите сделать что-то подобное?

Конструктор - это функция-член , где ваш объект фактически создается и вы можете удалить объект, как только он будет полностью построен, поэтому выполнение чего-то подобного -

class A
{
public:
    A()
    {
        delete this;
    }

    ~A()
    {
    }
};

приводит к неопределенному поведению .

ТакжеЧтобы добавить к этому, если вы выполняете delete this в деструкторе, это также не правильно, так как сам объект подвергается разрушению и выполнение delete this в деструкторе снова вызовет деструктор.

class A
{
public:
    A()
    {
    }

    ~A()
    {
        delete this;   // calls the destructor again. 
    }
};
0 голосов
/ 14 марта 2011

Предполагая, что ваш объект никогда не наследуется, это должно работать нормально.Ваш конструктор запускается, а затем вызывается деструктор.Если что-то наследует этот объект, оно сломается, так как этот конструктор будет вызываться перед наследующим конструктором.

...