2

我必须加深对调用构造函数的情况的理解。在此期间,我偶然发现了Microsoft 的这个示例

//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 和析构函数打印。微软表示,如果 thorw 被注释掉并且没有 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

但是我不能完全跟随。我认为这就是发生的事情:

  1. 主要constructor要求RVO rvo;
  2. 在 MyMethodconstructor中调用RVO rvo;
  3. 因为return (rvo);copyconstructor称为
  4. 在 MyMethoddestructor中为本地 RVO 调用
  5. destructor本地 rvo 调用In Main

这让我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;       
};
4

4 回答 4

1

不要混淆。如果没有返回值优化,会创建三个) 对象(包括用于通过复制构造函数进行复制的临时对象),因此三个对象正在被销毁(再次包括临时对象),所以一切都很好。

但是,使用 RVO,在复制时不会创建临时对象(对象将直接在调用者的堆栈帧中创建),您只会看到两个构造和两个破坏。

于 2012-09-19T06:55:33.863 回答
1

如果您仔细查看语句 rvo=MyMethod(5);

rvo 由 MyMethod 的返回对象赋值,返回对象应该在 main 函数的范围内构造。此对象未命名,是一个临时对象。这种对象的构造函数显示在输出中,乍一看并不明显。

于 2012-09-19T06:58:36.050 回答
0

rvo 在 main() 中构造

rvo 在 MyMethod 中构建

通过 return 语句从 MyMethod 中的 rvo 复制构造一个未命名的 RVO 对象

所有三个对象都被销毁

于 2012-09-19T06:55:39.773 回答
0

“在主构造函数中为RVO调用rvo;在MyMethod构造函数中为RVO调用rvo;为return(rvo);copyconstructor” 所以构造了三个对象,正常情况下应该有3个被销毁。返回的值也需要被破坏。

于 2012-09-19T06:56:08.930 回答