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,把内存还给系统,是不是等于恢复这块内存到最原始的空闲状态?
显式调用,只是作为一个普通的成员函数被调用了,内存并没有释放,保存a的地方没有发生过变化
这个取决于系统的内存分配策略
纯粹调析构函数只是成员函数调用而已
new出来的内存主要用来保存类的虚表和成员变量,delete是告诉系统,这块内存没有人用了
其他程序可以使用或者这个程序可以再利用整块内存了
你改下: ~A(){ cout << “destructor” << endl; a = 5; } ,就可以验证.
2.你delete aa后,在aa基础进行非法访问,本身就是不可预料的结果.
3.析构函数销毁对象,销毁的一般你程序自己申请的内存;operate delete才是删除类对象的分配的内存.delete 释放内存后,当前内存块会划分到空闲内存块. (所以频繁的申请内存,释放,会造成内存碎片).
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)是何用意。以上解释希望能对你有用
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++ 库以一种你并不知道的方式标记为空闲。至于他是不是与最原始的空闲状态一致,你也并不知道。但总之它空闲了,随时有可能被挪作他用。
1. a是在main返回的时候自动删除的。调用析构函数不会删除a,而且你的析构函数对a也没有任何影响。
2. pp的地址是&aa,也就是aa变量所在的地址而不是aa保存的A对象的地址。所以凭什么一样…
3. 你所谓的销毁对象其实是在被销毁前的清理操作,前面已经说了。内存释放/回收只是说这块内存可以拿来干别的用了,的确是空闲了,不过所谓的最原始的空闲状态无从谈起。