C++中对象创建与释放

127 篇文章 11 订阅
82 篇文章 5 订阅

创建对象有以下四种形式:

 
  1. #include <iostream>
  2. using namespace std;
  3. class A{
  4. private:
  5. int i;
  6. public:
  7. A(){ cout<<"调用没有参数的构造函数"<<endl; }
  8. A(int a):i(a){ cout<<"调用有一个参数的构造函数"<<endl; }
  9. ~A(){cout<<"成员变量为:"<<i<<"\t调用析构函数"<<endl;}
  10. };
  11. void main(){
  12. A a0; //形式一:直接声明一个对象
  13. A a1(1); //形式二:隐式调用A带一个参数的构造函数
  14. A a2 = A(2); //形式三:显式调用A带一个参数构造函数
  15. A *p = new A(3); //形式四:动态分配
  16. }

形式一:实际上等同于  A  a0 = A();调用不带参数的构造函数进行对象的创建

形式二:实际上等同于  A  a1 = A(1);调用带一个参数的构造函数进行对象的创建

形式三:与形式二相同,这三种形式其实都是按照参数调用对应的构造函数在栈中创建对象,使用完毕后,系统自动回收对象内存,无需手动释放。

形式四:在堆内存中动态开辟空间创建对象,需要手动释放内存。

还有一点需要注意“A a3();”编译和运行都没有问题,但是并没有创建对象

运行结果:

 

由图可以得出如下结果:

(1)创建对象需要调用对应的构造函数,释放对象需要调用析构函数。因为形式一对应的构造函数没有对对象进行初始化所以成员变量i出现随机数“-858993460”.

(2)析构的顺序与构造顺序相反,上面代码中构造顺序是a0,a1,a2 ;析构顺序是a2,a1,a0.

(3)在栈中创建的对象无需手动释放,系统自动回收。在堆中创建的对象需要手动释放。在运行结果中调用了4次构造函数,然而析构函数只执行了3次,没有释放指针p所指向的对象。在上面程序末尾加入代码delete p;p=NULL;运行结果如下:

堆中的对象也被删除了。

但需要注意的是delete p;只是释放了内存空间,指针p仍然指向那块空间,所以一定要将p指针置为NULL;

 
  1. #include <iostream>
  2. using namespace std;
  3. class A{
  4. private:
  5. int i;
  6. public:
  7. A(){ cout<<"调用没有参数的构造函数"<<endl; }
  8. A(int a):i(a){ cout<<"调用有一个参数的构造函数"<<endl; }
  9. ~A(){cout<<"成员变量为:"<<i<<"\t调用析构函数"<<endl;}
  10. };
  11. void main(){
  12. A a0; //方法一:直接声明一个对象
  13. A a1(1); //方法二:隐式调用A带一个参数的构造函数
  14. A a2 = A(2); //方法三:显式调用A带一个参数构造函数
  15. A *p = new A(3); //方法四:动态分配
  16. delete p;
  17. cout<<"delete后指针p指向的空间:"<<p<<endl;
  18. p=NULL;
  19. }

运行结果如下:



 

还需要注意的一点是,delete不能释放栈中的空间。我曾经犯过一个错误,错误代码如下:

 
  1. #include <iostream>
  2. using namespace std;
  3. class A{
  4. private:
  5. int i;
  6. public:
  7. A(){ cout<<"调用没有参数的构造函数"<<endl; }
  8. A(int a):i(a){ cout<<"调用有一个参数的构造函数"<<endl; }
  9. ~A(){cout<<"成员变量为:"<<i<<"\t调用析构函数"<<endl;}
  10. };
  11. void main(){
  12. A a(1);
  13. A *p1 = &a;
  14. delete p1; //希望释放栈中的对象
  15. }

编译没有问题,但运行出错。

所以delete一定要和new成对出现,delete释放的是动态开辟的内存。栈中的内存不需要咱们去释放,系统自己会回收。

 

如果构造函数有默认参数,则可能出现不知道调用哪个构造函数的问题

 
  1. #include <iostream>
  2. using namespace std;
  3. class A{
  4. private:
  5. int i;
  6. public:
  7. A(){cout<<"调用没有参数的构造函数"<<endl;}
  8. A(int a = 0):i(a){ cout<<"调用有一个参数的构造函数"<<endl; }
  9. };
  10. void main(){
  11. A a0;
  12. }

编译器不知道该调用哪一个构造函数,所以删除其中一个构造函数即可。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值