构造函数与析构函数(2)

      今天突然想到,上次提及的构造函数的执行时刻还不够全面。当对象做为参数传入函数时,会不会也引发构造函数的执行?

先试试下面的代码

void FuncA(CParent objTemp)
{
    cout<<"Begin of FuncA"<<endl;
    cout<<"End of FuncA"<<endl;
} 

int main()
{
    cout<<"Begin of main function"<<endl;
    CParent object;
    FuncA(object);
    cout<<"End of main function"<<endl;
    return 0;
}

运行结果如下:

Begin of main function
run constructor of CParent
Begin of FuncA
End of FuncA
run destructor  of CParent
End of main function
run destructor  of CParent
结果很神奇,居然跟我想像的完全不一样,构造函数调用了一次,而析构函数去调用了两次。知道传参的时候是会创建一个临时对象,那么构造函数应该会调用两次才对啊,难道直接把对象传进去不用创建临时对象? 那析构函数又为何调用了两次,没有两个不同的对象,哪来两个对象的析构....
跑去跟细菌讨论了一下,才知道原来还有拷贝构造函数这种东西。
 
在CParent类下添加一个方法如下:
CParent::CParent(const CParent& obj)
{
    cout<<"run the copy destructor of CParent"<<endl;
}
再次运行程序:
Begin of main function
run constructor of CParent
run the copy destructor of CParent
Begin of FuncA
End of FuncA
run destructor  of CParent
End of main function
run destructor  of CParent

结果如预期出现,果真是在传参时调用了拷贝构造函数,重新创建一个临时对象。这时我想,既然是创建了临时对象,那么在函数内部修改了对象属性,对原来的对象有没有影响?于是在类中添加一个属性,修改代码如下:

void FuncA(CParent objTemp)
{
    cout<<"Begin of FuncA"<<endl;
    objTemp.n++;
    cout<<objTemp.n<<endl;
    cout<<"End of FuncA"<<endl;
} 

int main()
{
    cout<<"Begin of main function"<<endl;
    CParent object;
    object.n = 0;
    cout<<object.n<<endl;
    FuncA(object);
    cout<<object.n<<endl;
    cout<<"End of main function"<<endl;
    return 0;
}
运行代码,出现
Begin of main function
run constructor of CParent
0
run the copy destructor of CParent
Begin of FuncA
1807010509
End of FuncA
run destructor  of CParent
0
End of main function
run destructor  of CParent

可以看出,不仅函数内改变临时对象属性并没对原对象产生影响,创建临时对象时也没有复制原对象的属性,使用这种方法传递对象是会出很大问题的。。。

那么有什么方法可以安全传递对象。我想指针是肯定没问题的,先不说,我想试试引用。

先修改代码如下:

void FuncA(CParent& objTemp)
{
    cout<<"Begin of FuncA"<<endl;
    cout<<"End of FuncA"<<endl;
} 

int main()
{
    cout<<"Begin of main function"<<endl;
    CParent object;
    FuncA(object);
    cout<<"End of main function"<<endl;
    return 0;
}

运行结果如下:

Begin of main function
run constructor of CParent
Begin of FuncA
End of FuncA
End of main function
run destructor  of CParent

构造函数跟析构函数都只调用了一次,应该是没有多创建对象了,不过我还是想证明一下。

再次修改代码:

void FuncA(CParent& objTemp)
{
    cout<<"Begin of FuncA"<<endl;
    cout<<&objTemp<<endl;
    cout<<"End of FuncA"<<endl;
} 

int main()
{
    cout<<"Begin of main function"<<endl;
    CParent object;
    cout<<&object<<endl;
    FuncA(object);
    cout<<"End of main function"<<endl;
    return 0;
}

运行一下:

Begin of main function
run constructor of CParent
0013FDDC
Begin of FuncA
0013FDDC
End of FuncA
End of main function
run destructor  of CParent
两个地址一样,那么肯定是同一个对象了。使用引用传递一个对象也是可行的!

转载于:https://www.cnblogs.com/Zimmem/articles/1124072.html

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值