析构函数和构造函数调用,示例对吗?

时间:2012-09-19 06:50:09

标签: c++ constructor

我不得不提高我对构造者被召唤的环境的理解。在此期间,我偶然发现了来自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

然而,我无法效仿。我认为这就是发生的事情:

  1. constructor
  2. 中调用主RVO rvo;
  3. 在MyMethod constructor中呼叫RVO rvo;
  4. 对于return (rvo);copyconstructor被称为
  5. 在MyMethod destructor调用本地RVO
  6. 在主要destructor中调用本地rvo
  7. 这使得我只有少于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 个答案:

答案 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” 所以构建了三个对象,在正常情况下应该有三个被破坏。返回的值也需要被破坏。