当一个C++对象被创建时,有两件事会发生:
(1)为对象分配内存.
(2)调用构造函数来初始化那个内存.
到目前为止,我们应该确保步骤 2)一定发生。C++强迫这样做是因为未初始化的对象是程序出错的主要原因。不用关心对象在哪里创建和如何创建的—-构造函数总是被调用。
然而,步骤1)可以以几种方式或在可选择的时间内发生:
1) 静态存储区域,存储空间在程序开始之前就可以分配。这个存储空间在程序的整个运行期间都存在。
2) 无论何时到达一个特殊的执行点(左花括号)时,存储单元都可以在栈上被创建。出了执行点(右花括号),这个存储单元自动被释放。这些栈分配运算内置在处理器的指令集中,非常有效。然而,在写程序的时候,必须知道需要多少个存储单元,以使编译器生成正确的指令。
3) 存储单元也可以从一块称为堆(也可称为自由存储单元)的地方分配。这称为动态内存分配,在运行时调用程序分配这些内存。我们也负责决定何时释放内存。这块内存的生存期由我们选择决定—而不受范围限制。
这三个区域经常被放在一块连续的物理存储单元里:静态内存、堆栈和堆(由编译器的作者决定它们的顺序),但没有一定的规则。堆栈可以在某一特定的地方,堆的实现可以通过调用由运算系统分配的一块存储单元来完成。
当一个C++对象被销毁时,会发生两件事:
(1)调用析构函数.
(2)释放内存.
下面通过一个例子:为类重载new,delete ,为数组重载new[], delete[] 来理解C++对象创建和销毁的过程.(说明:当我们重载运算符时,编译器为优先使用)
#include <new.h>
#include<stdio.h>
#include<iostream.h>
class widget{
int i[10];
public:
widget(){
cout<<"*";}
~widget(){cout<<"~";}
void * operator new(size_t sz){
cout<<"widget::new: "<<sz<<" bytes"<<endl;
return ::new char[sz];
}
void operator delete(void *p){
cout<<"widget::delete"<<endl;
::delete p;
}
void * operator new[](size_t sz){
cout <<"widget::new[]: "<<sz<<" bytes"<<endl;
return ::new char[sz];
}
void operator delete[](void *p){
cout<<"widget::delete[]"<<endl;
::delete []p;
}
};
void main(){
cout<<"new widget" <<endl;
widget *w=new widget;
cout <<"/n delete widget"<<endl;
delete w;
cout<<"/n new widget[25]" <<endl;
widget *wa= new widget[25];
cout<<"/n delete []widget"<<endl;
delete []wa;
};
运行结果:
new widget
widget::new: 40 bytes
*
delete widget
~widget::delete
new widget[25]
widget::new[]: 1004 bytes
*************************
delete []widget
~~~~~~~~~~~~~~~~~~~~~~~~~widget::delete[]
Press any key to continue