最近面试的时候被问到一个问题是,在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. unable to apply changes:plugins "App links assistant",firebase services won'

    新安装的android studio工具报错,本来以为只要在plugins中安装android support插件的,现在点击该插件还是不能apply,提示: unable to apply chan ...

  2. ios滑动流畅(丝般顺滑)滚动

    在ios html->body->list(少一个样式都不行!) html->body->list <!DOCTYPE html> <html lang=&q ...

  3. LeNet-5识别MINIST数据集

    LeNet-5 LeNet于90年代被提出,鉴于当时的计算能力和内存容量,直到2010年才能真正的实施这样的大规模计算.LeNet-5是LeCun于1998年提出的深度神经网络结构,总共包含7层网络( ...

  4. 20.C++- "&&","||"逻辑重载操作符的缺陷、","逗号重载操作符的分析

    "&&","||"逻辑重载操作符的缺陷 大家,都知道"&&","||"拥有"短 ...

  5. [jdoj1817]Drainage Ditches_网络流

    Drainage Ditches jdoj-1817 题目大意:网络流裸求最大流 注释:n(点数),m(边数)<=200. 想法:裸的网络流求最大流,用bfs+dfs,美其名曰dinic. 没有 ...

  6. docker 学习之一:docker 安装

    核心概念1. 镜像是一个只读的模板类似于安装系统用到的那个iso文件我们通过镜像来完成各种应用的部署. 2. docker容器镜像类似于操作系统而容器类似于虚拟机本身.它可以被启动.开始.停止.删除等 ...

  7. [Java] JDK 环境配置(图文)

    Windows10 上的安装配置 1.前往 JDK 官网下载对应 jdk 版本安装包: http://www.oracle.com/technetwork/java/javase/downloads/ ...

  8. (译文)开始学习Vue.js特性--Scoped Slots

    什么是scoped slots A scoped slot is a special type of slot that functions as a reusable template (that ...

  9. Python 二分查找

    (非递归实现) def binary_search(alist, item): first = 0 last = len(alist)-1 while first<=last: midpoint ...

  10. java8-Stream之数值流

    在Stream里元素都是对象,那么,当我们操作一个数字流的时候就不得不考虑一个问题,拆箱和装箱.虽然自动拆箱不需要我们处理,但依旧有隐含的成本在里面.Java8引入了3个原始类型特化流接口来解决这个问 ...