Что произойдет, если функция-член попытается выполнить delete this;
, как в конструкторе следующего класса?
class A
{
public:
A(int);
~A();
int *pi;
}
A::A(int i)
{
delete this;
pi = new int(i);
}
A::~A()
{
delete pi;
}
Что произойдет, если функция-член попытается выполнить delete this;
, как в конструкторе следующего класса?
class A
{
public:
A(int);
~A();
int *pi;
}
A::A(int i)
{
delete this;
pi = new int(i);
}
A::~A()
{
delete pi;
}
This С++ FAQ отвечает на это довольно хорошо, повторяя здесь:
До тех пор, пока вы будете осторожны, это нормально для объекта delete this
.
Вот как я определяю "осторожно":
Вы нарушаете # 3, обращаясь к pi
после delete this
Плохие вещи. Вы можете delete this;
, но, как правило, это очень плохая идея, и после этого вы не можете касаться каких-либо переменных-членов или функций-членов.
В общем случае вызов delete this
изнутри функции-члена хорошо определен, если он немного рискован.
Но это, вероятно, очень плохая идея, чтобы вызывать его из конструктора (я не знаю, если он четко определен). Зачем вам это делать?
Вы можете delete this
, но это предполагает, что экземпляр был создан с помощью new
и что вы больше не получаете доступа к каким-либо членам экземпляра.
В вашем примере почти то же самое произойдет, если вы сделали
class A
{
public:
A(int);
int *pi;
};
A::A(int i)
{
pi = new int(i);
}
int main()
{
A* p = new A(10);
delete p;
p->pi = new int; //bad stuff
//or
A a(20);
delete &a; //bad stuff
a.pi = new int; //more bad stuff
}
И даже более плохие вещи происходят, потому что, когда вы delete this
, член pi
объединяется, что приводит к деструктору, пытающемуся удалить обвисший указатель.
1) оператор delete работает только для объектов, выделенных с использованием нового оператора. Если объект создается с помощью new, мы можем удалить его, иначе поведение undefined.
class A {
public:
void fun(){
delete this;
}
};
int main(){
/* Following is Valid */
A *ptr = new A;
ptr->fun();
ptr = NULL // make ptr NULL to make sure that things are not accessed using ptr.
/* And following is Invalid: Undefined Behavior */
A a;
a.fun();
return 0;
}
2) После удаления этого действия любой элемент удаленного объекта не должен быть доступен после удаления.
class A {
int x;
public:
A() { x = 0;}
void fun() {
delete this;
/* Invalid: Undefined Behavior */
cout<<x;
}
};