“删除此”题 [英] "delete this" question

查看:49
本文介绍了“删除此”题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下代码是否合法,道德且可取?


#include< iostream>


A类{

私人:

int a;


public:

A():a(42){}

~A(){

std :: cout<< A'的析构函数叫做a,是 << a<< std :: endl;

}

};


B级:公共A {

私人:

int b;


public:

B():b(666){}

~B(){

std :: cout<< B'的析构函数叫做,b是 << b<< std :: endl;

}

void go(){删除此; }

};


int main(){

B * b =新B();

b-> go();

返回0;

}


具体来说,是B和A'删除此指针后,仍然允许析构函数访问它们的类''成员变量?


-

Christopher Benson-Manica |我*应该*知道我在说什么 - 如果我

ataru(at)cyberspace.org |不,我需要知道。火焰欢迎。

解决方案

Christopher Benson-Manica写道:

以下代码是否合法,道德,并且可取的?

#include< iostream>

A级{
私人:
int a;

公众:
A():a(42){}
~A(){
std :: cout<< A'的析构函数叫做a,是 << a<< std :: endl;
}
};

B类:公开A {
私人:
int b;
public:
B():b(666){}
~B(){
std :: cout<< B'的析构函数叫做,b是 << b<< std :: endl;
}
void go(){删除此; }
};

int main(){
B * b = new B();
b-> go();
返回0;
}

具体来说,在删除此指针后,B和A'的析构函数是否仍然允许访问其类的成员变量?



不,他们不是。但他们为什么需要呢?在你的代码中,析构函数

- 就像往常一样 - 在删除后没有被调用,而是作为它的一部分。

是的,你可以删除一个对象在其中一个成员函数

中,只要你确保之后没有任何东西被访问(即在

你的情况下,go()不会使用任何删除后的对象成员。


是否''删除这个;''是一个很好的设计 - 好吧,我会说这取决于

在哪里以及如何使用该课程。



* Christopher Benson-Manica:

以下是代码合法,道德和可取的?


是的,无论如何,没有。


#include< iostream>

A级{
私人:
int a;

公开:
A():a(42){}
~A(){
标准:: cout<< A'的析构函数叫做a,是 << a<< std :: endl;
}
};


用于多态但非虚拟析构函数:坏。


B级:公共A {
私有:
int b;

public:
B():b(666){}
~B(){
std :: cout<< B'的析构函数叫做,b是 << b<< std :: endl;
}
void go(){删除此; }
};


A和B的不同终身管理政策:不好。


B支持复制但需要动态分配:不好。


非I / O类的I / o:坏。


int main(){
B * b = new B();
b-> go();
返回0;
}

具体来说,B和A'的析构函数仍然允许访问
这个指针被删除后,他们的类''成员变量?




不,但他们不是。


-

答:因为它弄乱了人们通常阅读文字的顺序。

问:为什么这么糟糕?

A:热门发布。

问:usenet和电子邮件中最烦人的事情是什么?


Christopher Benson- Manica写道:

以下代码是否合法,道德和可取?
void B :: go(){删除此; }
B * b = new B();
b-> go();


C ++定义了在对象删除后从方法返回的行为。


其道德和建议是否是团队和项目决策。一些

框架封装了所有的所有者指针,因此调用者很少看到

''new''并且永远不会看到''delete''。在这种模式中,对象通常必须自行删除,并将所有链接指针通知为NULL

自己。


现在让你的代码变得非法:

#include< iostream>


B级;

A级{
私人:
int a;
B& m_b;
public:
A(B& b):a(42),m_b(b){}

~A(); B类:公共A {
public:

int b;
public:
B():b(666 ){}
~B(){
std :: cout<< B'的析构函数叫做,b是 << b<< std :: endl;
}
void go(){删除此; }
};


A ::〜A(){

std :: cout<< A'的析构函数叫做a,是 << a<< std :: endl;

std :: cout<< B已经破坏,因此访问b是非法的

<< m_b.b<< std :: endl;

}

int main(){
B * b = new B();
b-> go( );
返回0;
}


在销毁过程中,派生类子对象首先破坏,所以

访问其成员在整个

对象的存储版本发布之前的瞬间未定义。在实践中,我们的''b''很可能会返回

的正确值。

具体来说,B和A'的析构函数仍然允许访问
在删除此指针后,他们的类''成员变量?




他们的_own_ class'的成员,是的。他们也可以调用方法。销毁

就在发布前发生。


-

Phlip
http://www.c2.com/cgi/wiki?ZeekLand


Is the following code legal, moral, and advisable?

#include <iostream>

class A {
private:
int a;

public:
A() : a(42) {}
~A() {
std::cout << "A''s destructor called, a is " << a << std::endl;
}
};

class B : public A {
private:
int b;

public:
B() : b(666) {}
~B() {
std::cout << "B''s destructor called, b is " << b << std::endl;
}
void go() { delete this; }
};

int main() {
B *b=new B();
b->go();
return 0;
}

Specifically, are B and A''s destructors still permitted to access
their class'' member variables after the this pointer has been deleted?

--
Christopher Benson-Manica | I *should* know what I''m talking about - if I
ataru(at)cyberspace.org | don''t, I need to know. Flames welcome.

解决方案

Christopher Benson-Manica wrote:

Is the following code legal, moral, and advisable?

#include <iostream>

class A {
private:
int a;

public:
A() : a(42) {}
~A() {
std::cout << "A''s destructor called, a is " << a << std::endl;
}
};

class B : public A {
private:
int b;

public:
B() : b(666) {}
~B() {
std::cout << "B''s destructor called, b is " << b << std::endl;
}
void go() { delete this; }
};

int main() {
B *b=new B();
b->go();
return 0;
}

Specifically, are B and A''s destructors still permitted to access
their class'' member variables after the this pointer has been deleted?



No, they aren''t. But why would they need to? In your code, the destructors
are - just as usual - not called after the deletion, but as part of it.
And yes, you are allowed to delete an object in one of its member functions
as long as you make sure that nothing of it is accessed afterwards (i.e. in
your case, go() doesn''t use any members of the object after the delete).

Whether ''delete this;'' is a good design - well, I''d say that depends on
where and how the class is used.



* Christopher Benson-Manica:

Is the following code legal, moral, and advisable?
Yes, whatever, no.

#include <iostream>

class A {
private:
int a;

public:
A() : a(42) {}
~A() {
std::cout << "A''s destructor called, a is " << a << std::endl;
}
};
Intended for polymorphism but non-virtual destructor: bad.

class B : public A {
private:
int b;

public:
B() : b(666) {}
~B() {
std::cout << "B''s destructor called, b is " << b << std::endl;
}
void go() { delete this; }
};
Different lifetime management policies for A and B: bad.

B supports copying but requires dynamic allocation: bad.

I/o in non-i/o classes: bad.

int main() {
B *b=new B();
b->go();
return 0;
}

Specifically, are B and A''s destructors still permitted to access
their class'' member variables after the this pointer has been deleted?



No, but they don''t.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?


Christopher Benson-Manica wrote:

Is the following code legal, moral, and advisable? void B::go() { delete this; } B *b=new B();
b->go();
C++ defines the act of returning from a method after its object deletes.

Whether its moral and advisable is a team and project decision. Some
frameworks encapsulate all their owner pointers, so the caller rarely sees
''new'' and never sees ''delete''. Within this pattern, objects often must
delete themselves, and they notify all the linking pointers to NULL
themselves.

Now let''s make your code illegal:
#include <iostream>
class B;
class A {
private:
int a; B & m_b;
public: A(B &b) : a(42), m_b(b) {}
~A(); };

class B : public A { public:
int b;
public:
B() : b(666) {}
~B() {
std::cout << "B''s destructor called, b is " << b << std::endl;
}
void go() { delete this; }
};
A::~A() {
std::cout << "A''s destructor called, a is " << a << std::endl;
std::cout << "B has already destructed, so accessing b is illegal "
<< m_b.b << std::endl;
}
int main() {
B *b=new B();
b->go();
return 0;
}
During destruction, the derived class sub-object destructs first, so
accessing its members is undefined during the split second before the entire
object''s storage releases. In practice, our ''b'' will most likely return the
correct value.
Specifically, are B and A''s destructors still permitted to access
their class'' member variables after the this pointer has been deleted?



Their _own_ class''s members, yes. They can also call methods. Destruction
happens just before releasing.

--
Phlip
http://www.c2.com/cgi/wiki?ZeekLand


这篇关于“删除此”题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆