最近面试的时候被问到一个问题是,在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. Java异常机制简介

    什么是异常? 异常一般是指程序在编译期没有问题,但是在程序运行期出现的错误,一个程序会因为出现异常而终止运行,也就是我们常说的挂掉,在多线程下,异常只会影响所在的线程,对其他线程没有影响. Java异 ...

  2. HTML定位简介

    转载出处 定位一直是WEB标准应用中的难点,如果理不清楚定位那么可能应实现的效果实现不了,实现了的效果可能会走样.如果理清了定位的原理,那定位会让网页实现的更加完美. 定位的定义:在CSS中关于定位的 ...

  3. CXF-02: 使用CXF处理JavaBean式的复合类型和List集合类型

    Cat.java: package com.war3.ws.domain; public class Cat { private Integer id; private String name; pr ...

  4. TCP 详解

    计算机网络中比较中要的无非就是 TCP/IP 协议栈,以及应用层的 HTTP 和 HTTPS . 前几天一直炒的的比较火的就是 HTTP/2.0 了,但是其实 HTTP/2.0 早在2015年的时候就 ...

  5. 【Django】 初步学习

    这个系列(或者成不了一个系列..)预计会全程参考Vamei様的Django系列,膜一发.说句题外话,其实更加崇拜像Vamei那样的能够玩转生活.各个领域都能取得不小成就的人. [Django] ■ 概 ...

  6. Ubuntu安装Anaconda

    安装Anaconda的最简单方法是下载最新的Anaconda安装程序bash脚本,然后运行它. 在Anaconda Downloads页面找到最新版本的Anaconda for Python 3 .当 ...

  7. 201621123050 《Java程序设计》第8周学习总结

    1. 本周学习总结 以你喜欢的方式(思维导图或其他)归纳总结集合相关内容. 2. 书面作业 1. ArrayList代码分析 1.1 解释ArrayList的contains源代码 答:ArrayLi ...

  8. socketpair创建双向通信的管道(全双工通信)

    Linux下socketpair介绍: socketpair创建了一对无名的套接字描述符(只能在AF_UNIX域中使用),描述符存储于一个二元数组,例如sv[2] .这对套接字可以进行双工通信,每一个 ...

  9. Python 图片转字符画

    Python 图片转字符画 一.课程介绍 1. 课程来源 原创 2. 内容简介 本课程讲述怎样使用 Python 将图片转为字符画 3. 前置课程 Python编程语言 Linux 基础入门(新版) ...

  10. 基于协程的Python网络库gevent

    import gevent def test1(): print 12 gevent.sleep(0) print 34 def test2(): print 56 gevent.sleep(0) p ...