我不得不提高我对构造者被召唤的环境的理解。在此期间,我偶然发现了来自Microsoft的this example:
//RVO class is defined above in figure 4
#include <stdio.h>
RVO MyMethod (int i)
{
RVO rvo;
rvo.mem_var = i;
throw "I am throwing an exception!";
return (rvo);
}
int main()
{
RVO rvo;
try
{
rvo=MyMethod(5);
}
catch (char* str)
{
printf ("I caught the exception\n");
}
}
RVO
类在调用时只有构造函数,copyconsdtuctor和析构函数。微软声称,如果没有NRVO注意到并且没有NRVO,那么输出将是:
I am in constructor
I am in constructor
I am in copy constructor
I am in destructor
I am in destructor
I am in destructor
然而,我无法效仿。我认为这就是发生的事情:
constructor
RVO rvo;
constructor
中呼叫RVO rvo;
return (rvo);
,copyconstructor
被称为destructor
调用本地RVO destructor
中调用本地rvo 这使得我只有少于destructor
的电话,而不是微软宣布。我错过了什么?
对于完整性RVO
类:
class RVO
{
public:
RVO(){printf("I am in constructor\n");}
RVO (const RVO& c_RVO) {printf ("I am in copy constructor\n");}
~RVO(){printf ("I am in destructor\n");}
int mem_var;
};
答案 0 :(得分:1)
不要混淆。如果没有返回值优化,则会创建三个)对象(包括用于通过复制构造函数进行复制的临时对象),因此三个对象正在被摧毁(包括暂时的再次),所以这一切都很好。
使用RVO时,复制时不会创建临时对象(对象将直接在调用者的堆栈框架中创建),您将只看到两个构造和两个析构。
答案 1 :(得分:1)
如果仔细查看语句rvo = MyMethod(5);
rvo由MyMethod的返回对象赋值,返回对象应该在main函数的范围内构造。此对象未命名,是一个临时对象。输出中显示了这样一个对象的构造函数,第一次看起来并不明显。
答案 2 :(得分:0)
rvo是在main()
中构建的rvo是在MyMethod中构建的
一个未命名的RVO对象是通过返回语句从MyMethod中的rvo复制构造的
所有三个对象都被销毁
答案 3 :(得分:0)
“在主构造函数中调用RVO rvo;在MyMethod构造函数中调用RVO rvo;对于return(rvo); copyconstructor” 所以构建了三个对象,在正常情况下应该有三个被破坏。返回的值也需要被破坏。