利用栈和堆来定义对象的不同之处~~
我们在定义一个类的对象的时候,通常有两种方法:
- 采用栈来定义对象:Human unique;
- 采用堆来定义对象:Human *unique=new Human;
下面,我们通过一个程序来说明这两种方法的区别:
#include <iostream> using namespace std; class Human { public: Human(); ~Human(); int get()const{return *i;} void set(int x){*i=x;} private: int *i; }; int main() { cout<<"利用堆来定义对象:\n"; Human *tom=new Human; cout<<tom->get()<<endl; tom->set(0); cout<<tom->get()<<endl; cout<<endl; cout<<"利用栈来定义对象:\n"; Human unique; cout<<unique.get()<<endl; unique.set(0); cout<<unique.get()<<endl; return 0; } Human::Human() { cout<<"构造函数执行中...\n"; i=new int(10); } Human::~Human() { cout<<"析构函数执行中...\n"; delete i; }
该程序输出结果为:
对该结果的分析:
我们在程序的第16行和第24行分别采用了堆分配(new Human)和栈分配(Human unqiue)的方式来创建了两个对象。我们从输出可以清楚的看出来,只有在利用栈分配对象的时候,编译器在最后才会自动调用该类的析构函数来销毁这个对象;而对于利用堆分配的方式,编译器是不会自动释放其所占的内存的。只有通过程序员自己在最后调用delete来释放该内存区域。即,如果我们在上面程序的第20行上面加上
delete tom;
那么编译器才会调用析构函数来释放对象tom所占用的内存空间。结果如下图所示:
综上所述:
- 如果我们采用栈来定义对象。那么该对象会由系统自动为其在栈中间开辟空间,然后在释放对象的时候,比如说运行到右大括号的时候,系统也会自动的调用析构函数释放该对象所占用的内存空间。
- 如果我们采用堆来定义对象。即利用new的方式来分配空间给需要的对象,那么我们就必须要自行释放其所占用的内存,否则该对象所占用的内存会在整个程序全部结束的时候才会被操作系统回收。