拷贝构造函数和析构函数的调用

本文详细介绍了拷贝构造函数和析构函数的工作原理及其在C++中的自动调用时机。通过具体示例,展示了如何实现这两个特殊成员函数,以及它们在对象生命周期中的关键作用。

       拷贝构造函数会在三种情况下自动调用:

            1、声明类的一个对象A,并由同类型的对象B初始化,会自动调用拷贝构造函数产生对象B的一个副本,赋给对象A。

            2、函数返回类类型的一个值。即函数的返回类型是类,比如return A; 这时会自动调用拷贝构造函数,产生A的一个副本作为该函数的返回值。

            3、在传值调用的一个形参的位置,“插入”类类型的一个实参。比如函数void F(StaticClass A),F函数的参数是StaticClass类类型,当调用函数F时,比如F(B); 会自动调用拷贝构造函数,产生对象B的一个副本,再将这个副本传入到A中。

      析构函数是类的一个成员函数,它将在类的对象超出作用域时自动调用。换言之,如果程序包含一个局部对象(比如这个局部对象是在局部函数中定义的),而且这个局部对象是提供了析构函数的一个对象,那么在函数调用终止时,会自动调用析构函数销毁该局部对象。

       析构函数是用于销毁一个类的一个对象,且这个的数据成员含有指针或者该对象是使用了new关键字来创建的。

       为了有效的管理内存空间,我们应该在删除对象的同时释放由对象申请的内存空间。即完成申请空间的构造函数的反操作。析构函数的前面含有字符“~”,字符“~”表示求反,所以析构函数是构造函数的反操作。

      析构函数在什么时候会被系统自动调用呢?

      析构函数在删除对象时调用,程序结束时,将删除所有全局对象及程序中定义的对象,对在程序中创建的局部对象,则在程序退出该程序段时删除。请看下面的一段程序    

void DestroyDemo(int m1, int m2)
{
     StaticClass obj_3(m1,m2) ; //obj_3(3,300)的构造函数
}  //obj_3的析构函数,函数调用结束时,会自动调用该对象的析构函数

int main()
{
    StaticClass obj_1(1,100)  ;               //obj_1(1,100)的构造函数
    StaticClass *obj_2;
    obj_2 = new StaticClass(2,200) ;     //*obj_3(2,200)的构造函数
    DestroyDemo(3,300) ;
    delete obj_2 ;                                   //obj_2的析构函数,显示释放obj_2
} //obj_1的析构函数,,程序结束时,会自动调用该对象的析构函数

 

为了更好的说明拷贝构造函数和析构函数的调用情况,情况下面的一个程序:

#include <iostream>
using namespace std;

class A
{
public:
 //定义构造函数
 A(){cout << "执行构造函数创建一个对象\n" ;}
 //定义拷贝构造函数
 A(const A& X){cout << "执行拷贝构造函数创建该对象的副本\n" ;}
 //定义析构函数
 ~A() {cout << "执行析构函数删除该对象\n" ;}
};
//定义fun函数,其参数类型是A类型,返回值的类型是A
A fun(A one)
{
 return one ;
}

int main()
{
 A a ;//定义A类的一个对象a
 fun(a) ;
 return 0 ;
}

该程序的执行结果如下:

对照上面的程序逐一解释:

       第一句“执行构造函数创建一个对象”:这句是由主程序中A a ;这一句产生的,即在创建对象a时系统会自动调用默认的构造函数创建对象。

       第二句“执行拷贝构造函数创建该对象的副本”:这句是由fun(a); 产生的。首先函数fun的参数的类型是类,且是传值调用形参。根据上面系统自动调用拷贝构造函数的原则可知,这时系统会自动调用拷贝构造函数为对象a创建一个副本,创建好副本后,再将a的副本赋给形参one。

       第三句“执行拷贝构造函数创建该对象的副本”:这句是由return one ;产生的。因为函数fun的返回值类型是类。根据拷贝构造函数自动调用的原则可知,系统会自动调用拷贝构造函数为对象one创建一个副本,创建好该副本后,再将该副本作为函数的返回值进行返回。

       第四句“执行析构函数删除该对象”:这句是由于fun函数是有返回值的,且其返回值的类型的类,即其值是对象。由于在本程序中,我们只是调用了fun函数,并没有对其返回值进行处理。即没有赋给任何的对象,因此这个返回的临时对象(即是one的副本)也就被丢弃了。这时会自动调用析构函数来是否释放这个临时对象多占用的内存空间。

       第五句“执行析构函数删除该对象”:这句是由于fun函数已经调用结束,那么这时形参one所占用的内存将要被释放,所以会自动调用析构函数将one对象所占用的内存空间进行释放。

       第六句“执行析构函数删除该对象”:这句是由于main已经结束了,系统会释放到所以对象占用的内存空间,所以此时,系统会自动调用析构函数删除对象a所占用的内存空间,从而看到了该信息。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值