1 #include<iostream> 2 using namespace std; 3 4 class Object{ 5 void* data; 6 const int size; 7 const char id; 8 public: 9 Object(int sz, char c) :size(sz),id(c){ 10 data = new char[size]; 11 cout << "Constructor Object" << id << ",size=" << size << endl; 12 } 13 ~Object(){ 14 cout << "Destructing object" << id << endl; 15 delete[]data; 16 } 17 18 }; 19 20 int main(){ 21 Object* a = new Object(40,'a'); 22 delete a; 23 void* b = new Object(41,'b');//会调用构造函数 24 delete b;//不会调用析构函数 25 26 return 0;
}
首先我们来开一下这个类的内存模型。
在运行结果截图中,我们看到
Object* a = new Object(40,'a');
delete a;
可以正确的构造对象,在析构函数中也可以把用delete把data指针指向的内存释放掉。(在对void*类型的内存使用delete,并不会发生错误,仅仅是把内存释放掉。)但是在main函数中,我们看到delete知道它所操作的对象的类型是十分重要的。我们看到
void* b = new Object(41,'b');//会调用构造函数 delete b;//不会调用析构函数
在用delete删除b的操作中,我们只是对b指向的对象进行了释放,并没有调用构造函数,也就是说data指向的内存并没有被释放,而此时又没有指针指向刚才data指针指向的内存,从而造成了内存的丢失,更会造成内存的泄露。
这会有一个比较有意思的地方就是如果写下面的代码,
Object* pc=(Object*)malloc(sizeof(Object));//这个事情我们在new delete运算符与malloc free库函数的区别中讲到过,这时候不会调用构造函数,只会分配内存
delete pc;//而这句话因为pc是有类型的,不是void*所以会调用析构函数