代码如下:编译加上参数:-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.