最近面试的时候被问到一个问题是,在C++中,能否在类的成员函数中调用delete this,后来网上查了一下资料,关于这个问题说得比较好的有http://blog.sina.com.cn/s/blog_4b4cf2af0100ywgv.html

但是自己尝试了一下,还是有点区别的。

我写了如下代码:

class A {
public:
A() {
member = ;
}
~A() {
member = ;
}
int test() {
cout << member << endl;
cout << this << endl;
delete this;
cout << this << endl;
cout << member << endl;
}
private:
int member;
}; int main(){
A a;
a.test();
a.test();return ;
}

这份代码编译和运行都没有问题,在test中,打印了一个1,然后打印this的地址,delete this之后,再打印this的地址,发现没有变化,再打印member的值,发现变成了0

1. 在调用delete的时候,C++会帮我们调用这个对象的析构函数,因此member在析构函数中被置为了0

2. 调用delete只是告诉系统我们不需要这个对象的内存空间了,请求释放它,但并不会主动帮我们把这个指针置为null,它依然指向原来的内存地址

3 有趣的是,参考的博客说,在delete this之后,会释放掉类的对象的内存空间,因此如果不在delete this之后调用成员函数,那就没有任何问题,如果调用了成员函数,那就会出错,因为已经没有这个对象的成员了。但是我发现其实还是可以的。之后我又尝试了另外一种写法,代码如下:

class A {
public:
A() {
member = ;
}
~A() {
member = ;
}
int test() {
cout << member << endl;
cout << this << endl;
delete this;
cout << this << endl;
cout << member << endl;
}
private:
int member;
}; int main(){
A *a = new A();
a->test();
a->test();
return ;
}

这次我使用的是一个类的指针对象,然后为这个指针new一个新的对象,然后再次调用test函数,编译过程没有任何问题,但是在运行的时候会出现运行出错,并且在调用delete this之后,打印出来的member都是乱值。因此在类的成员函数中调用delete this,只是当这个对象是由一个指针new出来的对象有效果,并且会出现说delete this之后对象被释放,在delete this之后调用成员内容会出现不可知的错误。

那为什么会出现这两种不一样的结果呢?我个人猜测是因为,当我们是用A a = A()这样产生一个局部对象的时候,由于这个对象是被压入我们的函数栈当中,因此当你delete这个对象的指针,它也还是会存在这个函数栈当中,只有但函数栈回收的时候才会回收这个对象,而对于A *a = new A()这样的情况,a指针对应的对象是被分配到堆当中的,当我们delete的时候,系统就可以马上回收这个堆的内容并可能对堆的内容分布做一些优化和调整,这个时候对象对应的内容也就不存在了。

我再测试了一小段代码:

class A {
public:
A() {
member = ;
}
~A() {
member = ;
}
int test() {
cout << member << endl;
cout << this << endl;
delete this;
cout << this << endl;
cout << member << endl;
}
private:
int member;
int member2;
}; int main(){
A a = A();
A *ptr = &a;
delete ptr;
ptr->test();
return ;
}

用一个指针绑定a对象,a是一个局部的对象,然后delete这个指针的内容,然后用ptr去调用a的成员函数,这种情况也是编译和运行完全没有问题。

在类的成员函数中调用delete this的更多相关文章

  1. 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计

    类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...

  2. C++类的成员函数使用的一些小总结

    From: http://blog.csdn.net/xiayefanxing/article/details/7607506 这一阵做项目代码开发的时候,用到了在一个C++文件中使用另一个类的成员函 ...

  3. C++ 11 线程调用类的成员函数解决办法

    在C++中,_beginthreadex 创建线程是很麻烦的.要求入口函数必须是类的静态函数. 通常,可以采用thunk,或者模板来实现. 因C++ 11中引入了 std::async ,可以很好的解 ...

  4. 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)

    本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上?             成员函数可以被看作是类 ...

  5. 空类指针为什么可以调用类的成员函数 以及 A(){}和A();

    1. 代码及问题 #include <iostream> using namespace std; class A { public: A() {} //A *p = new A()时:此 ...

  6. VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)

    一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...

  7. 线程的函数中调用MFC对话框类的变量

    线程的函数中调用MFC对话框类的变量多线程传输文件的对话框 现在想要在对话框上添加一个进度条 为进度条映射变量m_progress这就需要在传输一段文件后就更新m_progress的值使进度条前进 也 ...

  8. C++点滴----关于类常成员函数

    关于C++中,类的常成员函数 声明样式为:   返回类型 <类标识符::>函数名称(参数表) const 一些说明: 1.const是函数声明的一部分,在函数的实现部分也需要加上const ...

  9. (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考

    昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"< ...

随机推荐

  1. zabbix监控redis性能

    创建采集脚本 mkdir -p /etc/zabbix/scripts chown -R zabbix.root /etc/zabbix/scripts vim redis_status.sh  #! ...

  2. C#添加背景音乐

    <MediaElement Name="audio"/> <Button Name="music" Content="点我有音乐哦& ...

  3. web服务器学习2---httpd-2.4.29虚拟目录及访问控制

    一 创建虚拟目录 环境准备: 系统:CentOS 7.4 软件:httpd-2.4.29 1.编辑主配置文件,添加命令运行子配置文件 vi /usr/local/httpd/conf/httpd.co ...

  4. c语言程序设计第3周编程作业(数字特征)

    题目内容: 对数字求特征值是常用的编码算法,奇偶特征是一种简单的特征值.对于一个整数,从个位开始对每一位数字编号,个位是1号,十位是2号,以此类推.这个整数在第n位上的数字记作x,如果x和n的奇偶性相 ...

  5. java 中的JDK封装的数据结构和算法解析(集合类)----链表 List 之 Vector (向量)

    Vector  看JDK解释(中文翻译)吧: Vector 类可以实现可增长的对象数组.与数组一样,它包含可以使用整数索引进行访问的组件.但是,Vector 的大小可以根据需要增大或缩小,以适应创建  ...

  6. "机器人防火墙":人机识别在应用安全及风控领域的一点实践

    美剧 WestWorld 第二集里有个场景十分有意思:游客来到西部世界公园,遇到了一个漂亮的女接待员,但无法区分对方是否是人类,于是产生了如下对话: Guest: "Are you real ...

  7. Jquery($第一天)【历史】

    一.什么是jQueryjQuery是一个JavaScript库,它通过封装原生的JavaScript函数得到一整套定义好的方法.它的作者是John Resig,于2006年创建的一个开源项目,随着越来 ...

  8. beat冲刺计划安排

    1. 团队成员 组长:郭晓迪 组员:钟平辉 柳政宇 徐航 曾瑞 2. 主要计划安排如下: 3. 详细日程任务安排

  9. 项目Alpha冲刺Day9

    一.会议照片 二.项目进展 1.今日安排 侧栏及相关刷新完成,项目结构小变动.个人信息和修改密码后台完成. 2.问题困难 前后台联调出现问题,配置修改了半天还没改好.好像是会话丢失,初步判断应该是后台 ...

  10. Scrum 冲刺 第六日

    Scrum 冲刺 第六日 目录 要求 项目链接 燃尽图 问题 今日任务 明日计划 成员贡献量 要求 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如 ...