在类的成员函数中调用delete this
最近面试的时候被问到一个问题是,在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的更多相关文章
- 在成员函数中调用虚函数(关于多态的注意事项)------新标准c++程序设计
类的成员函数之间可以互相调用.在成员函数(静态成员函数.构造函数和析构函数除外)中调用其他虚成员函数的语句是多态的.例如: #include<iostream> using namespa ...
- C++类的成员函数使用的一些小总结
From: http://blog.csdn.net/xiayefanxing/article/details/7607506 这一阵做项目代码开发的时候,用到了在一个C++文件中使用另一个类的成员函 ...
- C++ 11 线程调用类的成员函数解决办法
在C++中,_beginthreadex 创建线程是很麻烦的.要求入口函数必须是类的静态函数. 通常,可以采用thunk,或者模板来实现. 因C++ 11中引入了 std::async ,可以很好的解 ...
- 深入理解类成员函数的调用规则(理解成员函数的内存为什么不会反映在sizeof运算符上、类的静态绑定与动态绑定、虚函数表)
本文转载自:http://blog.51cto.com/9291927/2148695 总结: 一.成员函数的内存为什么不会反映在sizeof运算符上? 成员函数可以被看作是类 ...
- 空类指针为什么可以调用类的成员函数 以及 A(){}和A();
1. 代码及问题 #include <iostream> using namespace std; class A { public: A() {} //A *p = new A()时:此 ...
- VB6/VBA中跟踪鼠标移出窗体控件事件(类模块成员函数指针CHooker类应用)
一.关于起因 前几天发了一篇博文,是关于获取VB类模块成员函数指针的内容(http://www.cnblogs.com/alexywt/p/5880993.html):今天我就发一下我的应用实例. V ...
- 线程的函数中调用MFC对话框类的变量
线程的函数中调用MFC对话框类的变量多线程传输文件的对话框 现在想要在对话框上添加一个进度条 为进度条映射变量m_progress这就需要在传输一段文件后就更新m_progress的值使进度条前进 也 ...
- C++点滴----关于类常成员函数
关于C++中,类的常成员函数 声明样式为: 返回类型 <类标识符::>函数名称(参数表) const 一些说明: 1.const是函数声明的一部分,在函数的实现部分也需要加上const ...
- (转)c++类的成员函数存储方式(是否属于类的对象)---一道面试题引发的思考
昨天去面试一家公司,面试题中有一个题,自己没弄清楚,先记录如下: class D { public: void printA() { cout<<"printA"< ...
随机推荐
- Flyway--数据库版本管理和控制工具
1. Flyway 的主要任务是管理数据库的版本更新,在Flyway 中称每次数据库更新为一个migration ,为了更顺口,我们下面称之为数据库脚本.Flyway 支持SQL-based migr ...
- struts2和spring mvc的区别
在项目中使用struts2和spring mvc为了实现后台的业务代码和前台数据之间的传递,现在基本上不会有用struts2的了,几次面试问的最多的关于struts2的问题就是struts2和spri ...
- Java多线程:synchronized关键字和Lock
一.synchronized synchronized关键字可以用于声明方法,也可以用来声明代码块,下面分别看一下具体的场景(摘抄自<大型网站系统与Java中间件实践>) 案例一:其中fo ...
- java排序算法(七):折半插入排序
java排序算法(七):折半插入排序 折半插入排序法又称为二分插入排序法,是直接插入排序法的改良版本,也需要执行i-1趟插入.不同之处在于第i趟插入.先找出第i+1个元素应该插入的位置.假设前i个数据 ...
- python入门(Python和Pycharm安装)
Python简介 Python是一种计算机程序设计语言,它结合了解释性.编译性.互动性和面向对象的脚本语言,非常简单易用.Python 的设计具有很强的可读性,相比其他语言经常使用英文关键字,其他 ...
- vs运行单个cpp文件
打开vs,新建项目,左侧win32见上图,右侧 win32控制台应用程序,填好名称后,确定----下一步,如下图,空项目 紧接着如下图,通过现有项添加自己的cpp文件,便可以运行了
- 20162318 实验二《Java面向对象程序设计》实验报告
北京电子科技学院(BESTI) 实 验 报 告 课程:程序设计与数据结构 班级:1623班 姓名:张泰毓 指导老师:娄老师.王老师 实验日期:2017年4月14日 实验密级:非密级 实验器材:带Lin ...
- SQLAlchemy 教程 —— 基础入门篇
SQLAlchemy 教程 -- 基础入门篇 一.课程简介 1.1 实验内容 本课程带领大家使用 SQLAlchemy 连接 MySQL 数据库,创建一个博客应用所需要的数据表,并介绍了使用 SQLA ...
- Java HashMap工作原理及实现
Java HashMap工作原理及实现 2016/03/20 | 分类: 基础技术 | 0 条评论 | 标签: HASHMAP 分享到:3 原文出处: Yikun 1. 概述 从本文你可以学习到: 什 ...
- 51Nod P1100 斜率最大
传送门: https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1100 由于2 <= N <= 10000, 所以 ...