【问题标题】:Why destructor is not getting called for anonymous objects?为什么没有为匿名对象调用析构函数?
【发布时间】:2015-06-26 05:00:39
【问题描述】:

在工作时,我遇到了一段奇怪/令人困惑的代码,我觉得它与 anonymous object 生命周期概念有关。以下是示例代码:

#include<iostream>
#include<string>

class A {
private:
    int i;
    std::string s;
public:
    A(int ii, std::string ss = "Hello") { i = ii; s = ss; }
    void Display() { std::cout<<i<<"\n"; }
    ~A() { std::cout<<"A::~A()"<<"\n";}
};

void function()
{
    A a = 1;
    //A a = A(1);
    a.Display();
}

int main()
{
    function();
    return 0;
}

VS2010中的输出1(如果A a = 1)

 1
  A::~A()

VS2010中的Output2(If A a = A(1))

A::~A()
1
A::~A()

output2 非常有意义,因为 destructor 被调用了两次(包括匿名)对象。

但是 output1 让我感到困惑,无法理解为什么 destructor 被调用一次(不是匿名的)对象。

A a = 1;

上面的行将调用类A的复制构造函数(A(const A&amp; rhs)),编译器应该使用参数1为其创建匿名对象。如果是这种情况,应该调用两次析构函数。

有人可以向我解释一下这种行为吗?可能是我遗漏了一些明显的东西。

【问题讨论】:

    标签: c++ oop c++11 copy-constructor anonymous


    【解决方案1】:

    A a = A(1); 等价于A a = 1;。但是,在这两种情况下,copy elision 都可能发生:A(1) 实际上是直接构造成a,而不是单独构造然后复制或移动。

    由编译器决定是否在其允许的任何场景中执行复制省略(如上面的链接中所述)。

    【讨论】:

      【解决方案2】:

      您的编译器正在删除 A a = 1 的副本,但不会删除 A a = A(1); 的副本,gcc 在这两种情况下都能够删除 elide 的副本,这可以使用 -fno-elide-constructors 进行测试。

      【讨论】:

      • fno-elide-constructors 标志对理解这一点非常有用。
      猜你喜欢
      • 1970-01-01
      • 2018-11-19
      • 2010-10-16
      • 1970-01-01
      • 2014-08-26
      • 2014-06-13
      • 2019-01-29
      • 2011-06-17
      • 2020-02-17
      相关资源
      最近更新 更多