关于析构函数和构造函数的调用

代码如下:编译加上参数:-fno-elide-constructors,其中析构函数还有问题,请大神指导
#include <iostream>
using namespace std;
class CNumber
{
public:
    CNumber()
    {
        m_nNumber=10;
        cout<<"构造函数"<<endl;

    }
    ~CNumber()
    {
        cout<<"析构函数"<<endl;
    };
    CNumber(const CNumber &m)
    {
        cout<<"拷贝构造函数"<<endl;
    }
    CNumber &operator=(CNumber m)
    {
        //cout<<"重载赋值"<<endl;
    }
    int m_nNumber;
};
CNumber func(CNumber obj)
{

    CNumber m=obj; //调用一次拷贝构造函数 3
    return m;  //调用一次拷贝构造函数,拷贝一份临时对象返回 4
               //同时这里调用2次析构函数,析构m和obj对象
}
int main()
{
    CNumber Number;//调用构造函数 1
    CNumber m=func(Number);//这里首先先将Number拷贝一份作为func的参数,调用一次构造函数 2
                           //func函数返回的对象拷贝给m,调用一次拷贝构造函数 5,调用一次析构函数,析构掉;临时对象
    return 0;//析构对象Number,m,调用两次析构函数

}所以总共调用了5次构造函数,5次析构函数。

我们来看看汇编:main函数

Dump of assembler code for function main():
push   %rbp
mov    %rsp,%rbp
push   %rbx
sub    $0x48,%rsp
mov    %fs:0x28,%rax
mov    %rax,-0x18(%rbp)
xor    %eax,%eax
lea    -0x50(%rbp),%rax
mov    %rax,%rdi
callq  0x400b86 <CNumber::CNumber()>//调用一次构造函数,构造Number对象     1
lea    -0x50(%rbp),%rdx
lea    -0x30(%rbp),%rax
mov    %rdx,%rsi
mov    %rax,%rdi
callq  0x400be8 <CNumber::CNumber(CNumber const&)>//把NUmber拷贝一份作为func的参数,拷贝构造  2
lea    -0x20(%rbp),%rax
lea    -0x30(%rbp),%rdx
mov    %rdx,%rsi
mov    %rax,%rdi
callq  0x4009b6 <func(CNumber)> //func函数里边调用了两次 3,4,分析见func函数的栈帧
lea    -0x20(%rbp),%rdx
lea    -0x40(%rbp),%rax
mov    %rdx,%rsi
mov    %rax,%rdi
callq  0x400be8 <CNumber::CNumber(CNumber const&)>//func的返回的临时对象拷贝给m   5
lea    -0x20(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()>  //析构func返回的临时对象 3
lea    -0x30(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()>  //析构member 4
mov    $0x0,%ebx
lea    -0x40(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()>//析构m 5
lea    -0x50(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()> //这些析构怎么来的?请大神指导,总共调用了5次构造,为什么有这么多析构
mov    %ebx,%eax
mov    -0x18(%rbp),%rcx
xor    %fs:0x28,%rcx
je     0x400b2b <main()+230>
jmp    0x400b26 <main()+225>
mov    %rax,%rbx
lea    -0x20(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()> //?
jmp    0x400afe <main()+185>
mov    %rax,%rbx
lea    -0x30(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()>//?
jmp    0x400b0f <main()+202>
mov    %rax,%rbx
lea    -0x50(%rbp),%rax
mov    %rax,%rdi
callq  0x400bbc <CNumber::~CNumber()>//?
mov    %rbx,%rax
mov    %rax,%rdi
callq  0x4008a0 <_Unwind_Resume@plt>
callq  0x400860 <__stack_chk_fail@plt>
add    $0x48,%rsp
pop    %rbx
pop    %rbp
retq   
End of assembler dump.

func函数:

Dump of assembler code for function func(CNumber):
push   %rbp
mov    %rsp,%rbp
push   %rbx
sub    $0x28,%rsp
mov    %rdi,-0x28(%rbp)
mov    %rsi,-0x30(%rbp)
mov    %fs:0x28,%rax
mov    %rax,-0x18(%rbp)
xor    %eax,%eax
mov    -0x30(%rbp),%rdx
lea    -0x20(%rbp),%rax
mov    %rdx,%rsi
mov    %rax,%rdi
callq  0x400bec <CNumber::CNumber(CNumber const&)>//构造m 3
lea    -0x20(%rbp),%rdx
mov    -0x28(%rbp),%rax
mov    %rdx,%rsi
mov    %rax,%rdi
callq  0x400bec <CNumber::CNumber(CNumber const&)>//构造要返回的临时对象4
nop
lea    -0x20(%rbp),%rax
mov    %rax,%rdi
callq  0x400bb2 <CNumber::~CNumber()>//销毁传进来的参数obj,析构 1
nop
mov    -0x28(%rbp),%rax
mov    -0x18(%rbp),%rcx
xor    %fs:0x28,%rcx
je     0x400a3e <func(CNumber)+136>
jmp    0x400a39 <func(CNumber)+131>
mov    %rax,%rbx
lea    -0x20(%rbp),%rax
mov    %rax,%rdi
callq  0x400bb2 <CNumber::~CNumber()>//销毁对象m,析构 2
mov    %rbx,%rax
mov    %rax,%rdi
callq  0x4008a0 <_Unwind_Resume@plt>
callq  0x400860 <__stack_chk_fail@plt>
add    $0x28,%rsp
pop    %rbx
pop    %rbp
retq   
End of assembler dump.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值