析构函数和delete

C++语言 码拜 9年前 (2015-10-08) 1652次浏览
class A
{
public:
    A(int i = 3){  a = i; }
    ~A(){  cout << "destructor" << endl;  }
    int value(){return a;}
private:
    int a;
};
int main()
{
    A a;
    A* ptr = &a;
    cout << &a << endl;   //输出a的地址
    a.~A();   // 显式调用析构函数
    cout << (*ptr).value() << endl;   //这里输出默认的3;
    A *p = new(&a) A(10);   //这里会调用一次析构函数 输出 destructor
    cout << p << endl;    //输出的是和a一样的地址
    cout << a.value() << endl;   //输出10
    cout << p->value() << endl;   //输出10


    A* aa = new A();
    A* ptrr = aa;
    cout << aa << endl;
    delete aa; //调用delete了
    cout << (*ptrr).value() << endl;  //这里输出了0,而不是3;
    cout << ptrr << endl;   //这里输出的是和aa一样的地址了
    cout << aa << endl;
    A* pp = new(&aa) A(10);
    cout << pp << endl;  //这里输出的是和aa 不一样的地址。
    return 0;
}

变量名字取得有点挫,有这么几个疑惑:
1. 前面,当调用析构函数的时候,析构完,为什么可以用ptr去调用value函数? 而且调用后的值居然没有变,这是为什么?

2.后面,调用delete之后,这时候,new出来的pp和原先的aa 为什么地址就不一样了呢?

3.内存释放,内存回收,销毁对象这几个概念有点糊涂,
析构函数销毁对象,不回收内存,那那块内存里存的是啥?
delete,把内存还给系统,是不是等于恢复这块内存到最原始的空闲状态?

方案推荐指数:10
引用

1. 前面,当调用析构函数的时候,析构完,为什么可以用ptr去调用value函数? 而且调用后的值居然没有变,这是为什么?

显式调用,只是作为一个普通的成员函数被调用了,内存并没有释放,保存a的地方没有发生过变化

引用

2.后面,调用delete之后,这时候,new出来的pp和原先的aa 为什么地址就不一样了呢?

这个取决于系统的内存分配策略

引用

3.内存释放,内存回收,销毁对象这几个概念有点糊涂,
析构函数销毁对象,不回收内存,那那块内存里存的是啥?
delete,把内存还给系统,是不是等于恢复这块内存到最原始的空闲状态?

纯粹调析构函数只是成员函数调用而已
new出来的内存主要用来保存类的虚表和成员变量,delete是告诉系统,这块内存没有人用了
其他程序可以使用或者这个程序可以再利用整块内存了

方案推荐指数:10
1. 主动调用的析构函数,你并没有释放内存;Delete执行,会进行两部操作,调用析构,然后调用operate delete;你没有清除对象内存,请不要搞混,对象内存删除和析构函数调用的区别,两个不同步奏;
 你改下: ~A(){  cout << “destructor” << endl;  a = 5; }  ,就可以验证.
2.你delete aa后,在aa基础进行非法访问,本身就是不可预料的结果.
3.析构函数销毁对象,销毁的一般你程序自己申请的内存;operate delete才是删除类对象的分配的内存.delete 释放内存后,当前内存块会划分到空闲内存块. (所以频繁的申请内存,释放,会造成内存碎片).
方案推荐指数:5
这里主要是析构函数和new的用法
1.首先,new得用法有一下几种
  1> 创建变量          pointer_type = new  type               对应的初始化如: int *p = new int(10) ,    
   2>创建动态数组   pointer_type = new type[]
  而类的创建和初始化和变量类似,只不过在创建类时,new class(参数),调用的是类对应的构造函数
2.析构函数
   析构函数的意义是将new在堆中申请的对象释放掉。但此处释放,并非把原先的内容给擦除,而只是告诉系统这块内存我不用了,可以分配给其他进程使用。这也就是为什么电脑有些数据是可以恢复的原因
    其次,虽说使用析构函数释放了内存,但是指针仍然记录之前的内存的位置,所以仍然可以访问以前的数据。
3.  A *p = new(&a) A(10);      类似于这种new的用法我还没见过。不知楼主new(&a)是何用意。以上解释希望能对你有用
方案推荐指数:10

1. 这是未定义行为,得到什么结果都有可能。至于为什么是这个结果,要问你的编译器/操作系统。
2.  p = new(&a) A(10); pp = new(&aa) A(10);
    之后 p == &a , pp == &aa 。
   这里实际应该是 pp = new (aa) A(10) 才对。之后 pp == aa。
3. “析构函数销毁对象,不回收内存,那那块内存里存的是啥?”
   内存的每一位不是1就是0,不存在飘忽不定的状态。但是,具体是啥,需要问你编译器/操作系统/CPU/内存了。你可以打出来看看,但是不要期望你总能得到这样的结果。
“delete,把内存还给系统,是不是等于恢复这块内存到最原始的空闲状态?”
这块内存会被 C++ 库以一种你并不知道的方式标记为空闲。至于他是不是与最原始的空闲状态一致,你也并不知道。但总之它空闲了,随时有可能被挪作他用。

方案推荐指数:15
析构函数是对象被删除前会被调用的函数,本身并不会删除对象。析构函数的存在意义是让你在对象删除前有机会清理你的对象(比如你的对象成员有一个是new出来的指针,你需要在析构函数返回的时候保证这个指针已经被delete了)。主动调用析构函数正如前面很多人所说,就是调用了个函数输出个字符串而已。

1. a是在main返回的时候自动删除的。调用析构函数不会删除a,而且你的析构函数对a也没有任何影响。

 2. pp的地址是&aa,也就是aa变量所在的地址而不是aa保存的A对象的地址。所以凭什么一样…

 3. 你所谓的销毁对象其实是在被销毁前的清理操作,前面已经说了。内存释放/回收只是说这块内存可以拿来干别的用了,的确是空闲了,不过所谓的最原始的空闲状态无从谈起。


CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明析构函数和delete
喜欢 (0)
[1034331897@qq.com]
分享 (0)