所以这是代码:
#include <iostream>
using namespace std;
class C {
public:
C() {i = 6; cout << "A:" << i << endl;}
C(int i0) {i = i0; cout << "B:" << i << endl;}
~C() {cout << "C:" << i << endl;}
private:
int i;
};
int main(int argc, char* argv[]) {
cout << "X" << endl;
C *c = new C;
cout << "Y" << endl;
}
Run Code Online (Sandbox Code Playgroud)
由于某种原因,该代码的输出是
X
A:6
Y
Run Code Online (Sandbox Code Playgroud)
由于某种原因,一旦到达代码末尾就不会调用析构函数(C:6).这是为什么?此代码也调用析构函数:
#include <iostream>
using namespace std;
class C {
public:
C() {i = 0; cout << "A:" << i << endl;}
C(int i0) {i = i0; cout << "B:" << i << endl;}
~C() {cout << "C:" << i << endl;}
private:
int i;
};
int main(int argc, char* argv[]) {
cout << "X" << endl;
C c;
cout << "Y" << endl;
}
Run Code Online (Sandbox Code Playgroud)
Ane*_*dar 10
因为你忘了写
delete c;
Run Code Online (Sandbox Code Playgroud)
如果你只是在你的程序中继续而不删除用new实例化的变量,你将导致内存泄漏.
编辑,因为您编辑了您的问题:
如果你写的东西像
C c;
C c{1};
C c = C{1};
Run Code Online (Sandbox Code Playgroud)
您创建具有自动存储持续时间的变量.一旦在退出中声明它的函数它将超出范围(或者更精确:一旦在退出时声明它的块).在这种情况下,将自动调用构造函数.
如果你写
C* c = new C{};
Run Code Online (Sandbox Code Playgroud)
你创建一个指向(新)C的指针.指针本身具有自动存储持续时间,这意味着c也将超出范围.但是指针只保存C类对象的地址.只有在调用时才会删除此对象delete c;.如果你不调用delete,你的程序会"忘记"对象的地址,但它不会释放内存或破坏对象.那是内存泄漏.
但是一旦程序结束,所有内存都被释放(不调用析构函数),所以在你的小例子中你不会注意到.
你需要自己直接调用析构函数是非常罕见的.
当一个对象被销毁时,通过超出堆栈实例的范围或者deleted为堆实例来自动调用析构函数.因此,您的析构函数未被调用的事实告诉您一些事情:对象正在丢失或泄露.
new从堆内存中创建一个新的对象实例,并打开一个契约,当不再需要该对象时,您将负责调用delete将其返回到堆中.(或者delete []如果你分配一个数组)
在您的代码中,您永远不会delete创建您的实例.
#include <iostream>
using namespace std;
class C {
public:
C() : m_i(6) { cout << "A:" << m_i << endl;}
C(int i_) : m_i(i_) { cout << "B:" << m_i << endl;}
~C() {cout << "C:" << m_i << endl;}
private:
int m_i;
};
int main(int argc, char* argv[]) {
cout << "X\n";
C* c = new C;
C stackC;
cout << "Y\n";
delete c;
cout << "Z\n";
}
Run Code Online (Sandbox Code Playgroud)
现场演示:http://ideone.com/iuZim4
| 归档时间: |
|
| 查看次数: |
526 次 |
| 最近记录: |