函数调用完成返回对象后无法解释析构函数调用
Cannot explain a destructor call after a function call is done returning an object
我尝试了 运行 下面的代码,但我不明白何时以及为什么会在 myA=foo(myOtherB)
.
行调用析构函数
我的问题是,在 foo 函数 return 的 A 对象之后,从 'input' 复制构造它并打印 A copyctor,operator=
被称为打印 'Aop' 然后析构函数被调用打印 A dtor.
为什么此时调用析构函数而不是在 operator=
调用之前的 return 之后?
我遇到的另一个问题是,如果我使用 return A(2)
而不是 return input
构造函数 A 不会调用打印 A 构造函数...
谁能解释一下?我很抱歉代码有点复杂。
#include <iostream>
using namespace std;
class A
{
public:
int x;
A(){ cout<<"A ctor"<<endl; }
A(const A& a){cout<<"A copyctor"<<endl; }
virtual~A(){ cout<<"A dtor"<<endl;}
virtual void foo(){ cout<<"Afoo()"<<endl;}
virtual A& operator=(const A&rhs){cout<<"Aop="<<endl; }
A(int _x)
{
x=_x;
}
};
class B:public A
{
public:
B(){ cout<<"B ctor"<<endl; }
virtual~B(){ cout<<"B dtor"<<endl; }
virtual void foo(){ cout<<"B foo()"<<endl; }
protected:
A mInstanceOfA;
};
A foo(A& input)
{ input.foo(); return input; //return A(2); does not call the A constructor }
int main()
{
B myOtherB;
A myA;
myA=foo(myOtherB);
}
你returnby value,也就是说你return的值被复制到一个临时对象,一个后来被破坏的对象。
return A();
这叫做most vexing parse。
您不是在调用 A
的构造函数(不是创建新实例),而是声明一个 returns A 的函数(阅读 link 以获得进一步且可能更正确的解释)。
您可以通过以下方式调用构造函数:
return A{2};
这称为 Uniform initialization syntax
(C++ 11 及更高版本)
A myA;
myA=foo(myOtherB);
在这种情况下,您首先创建一个新的 A
对象 (myA
),然后将该变量分配给 foo
函数的 return 值。
由于第二行,这将调用赋值运算符。
您将 foo
return 的值复制到 myA
变量。
当已经创建的myA
变量被重新赋值时,旧值将被销毁,从而调用destructor
.
我认为你想要的是:
A myA = foo(myOtherB);
I tried running the code below and i do not understand when and why
does the destructor get called at the line myA=foo(myOtherB).
由于 RAII.
,析构函数将在主函数的最后一个大括号之前调用
Why is the destructor getting called at this point and not right after
the return before the operator= call?
我已经在上面回答了这个问题,对象范围很重要。只要您的对象超出范围,就会调用析构函数。
Another problem i have is that if i use return A(2) instead of return
input constructor A does not get called printing A ctor...
A foo(A& input)
{ input.foo(); return input; //return A(2); does not call the A constructor }
您正在返回一个现有的对象输入,您的函数将其作为引用接收,因此系统无需通过调用构造函数来创建对象。
我尝试了 运行 下面的代码,但我不明白何时以及为什么会在 myA=foo(myOtherB)
.
我的问题是,在 foo 函数 return 的 A 对象之后,从 'input' 复制构造它并打印 A copyctor,operator=
被称为打印 'Aop' 然后析构函数被调用打印 A dtor.
为什么此时调用析构函数而不是在 operator=
调用之前的 return 之后?
我遇到的另一个问题是,如果我使用 return A(2)
而不是 return input
构造函数 A 不会调用打印 A 构造函数...
谁能解释一下?我很抱歉代码有点复杂。
#include <iostream>
using namespace std;
class A
{
public:
int x;
A(){ cout<<"A ctor"<<endl; }
A(const A& a){cout<<"A copyctor"<<endl; }
virtual~A(){ cout<<"A dtor"<<endl;}
virtual void foo(){ cout<<"Afoo()"<<endl;}
virtual A& operator=(const A&rhs){cout<<"Aop="<<endl; }
A(int _x)
{
x=_x;
}
};
class B:public A
{
public:
B(){ cout<<"B ctor"<<endl; }
virtual~B(){ cout<<"B dtor"<<endl; }
virtual void foo(){ cout<<"B foo()"<<endl; }
protected:
A mInstanceOfA;
};
A foo(A& input)
{ input.foo(); return input; //return A(2); does not call the A constructor }
int main()
{
B myOtherB;
A myA;
myA=foo(myOtherB);
}
你returnby value,也就是说你return的值被复制到一个临时对象,一个后来被破坏的对象。
return A();
这叫做most vexing parse。
您不是在调用 A
的构造函数(不是创建新实例),而是声明一个 returns A 的函数(阅读 link 以获得进一步且可能更正确的解释)。
您可以通过以下方式调用构造函数:
return A{2};
这称为 Uniform initialization syntax
(C++ 11 及更高版本)
A myA;
myA=foo(myOtherB);
在这种情况下,您首先创建一个新的 A
对象 (myA
),然后将该变量分配给 foo
函数的 return 值。
由于第二行,这将调用赋值运算符。
您将 foo
return 的值复制到 myA
变量。
当已经创建的myA
变量被重新赋值时,旧值将被销毁,从而调用destructor
.
我认为你想要的是:
A myA = foo(myOtherB);
I tried running the code below and i do not understand when and why does the destructor get called at the line myA=foo(myOtherB).
由于 RAII.
,析构函数将在主函数的最后一个大括号之前调用Why is the destructor getting called at this point and not right after the return before the operator= call?
我已经在上面回答了这个问题,对象范围很重要。只要您的对象超出范围,就会调用析构函数。
Another problem i have is that if i use return A(2) instead of return input constructor A does not get called printing A ctor...
A foo(A& input)
{ input.foo(); return input; //return A(2); does not call the A constructor }
您正在返回一个现有的对象输入,您的函数将其作为引用接收,因此系统无需通过调用构造函数来创建对象。