【问题标题】:Lifetime of objects in c++c++中对象的生命周期
【发布时间】:2019-03-10 17:28:16
【问题描述】:
class Entity
{
  public:
    int a;
    Entity(int t)
      :a(t)
    {
        std::cout << "Constructor !" << std::endl;
    }
    ~Entity()
    {
        std::cout << "Destructor !" << std::endl;
    }

    Entity(Entity& o)
    {
        std::cout << "Copied !" << std::endl;
        this->a = o.a;
    }
};

Entity hi()
{
    Entity oi(3);
   return oi;
} 

int main()
{
  {
        Entity o(1);
        o = hi();
  }
     std::cin.get();
}

输出:

构造函数!

构造函数!

复制!

析构函数!

析构函数!

析构函数!


我创建了两个对象并复制了一个,所以三个构造函数和三个析构函数。

【问题讨论】:

  • Entity(Entity&amp; o) 也是一个构造函数。
  • 您需要检测复制构造函数。此外,三法则 - 你可能也想要一个赋值运算符。
  • 对不起。我不明白。
  • 是的。我知道复制构造函数
  • @Bubeshp return oi; -- 这是做什么的?除非调用 RVO,否则会创建一个副本。仅仅因为 you 没有显式创建对象并不意味着编译器没有创建对象。

标签: c++ constructor destructor object-lifetime


【解决方案1】:

您的“已复制!”输出中的行来自复制构造函数,因此您正在创建三个对象,而不仅仅是两个(然后您正在销毁所有三个,正如预期的那样)。

请注意,复制构造函数通常应该通过const 引用来获取其参数。猜测一下,您可能正在使用 Microsoft 的 C++ 编译器,它将临时绑定到非 const 引用。

另外请注意,如果您启用优化,您可能会看到只有两个构造函数和两个析构函数,而不会发生复制构造。使用足够新的 (C++17) 编译器,即使您不启用优化也应该会发生这种情况(复制省略已成为强制性)。

【讨论】:

  • 所以复制构造函数创建了具有主函数范围的临时对象(具有来自 hi() 中对象的值)。并将临时对象中的值复制到 object(o) 中?
  • @Bubeshp:是的,hi() 创建并返回一个对象,o 是从它返回的对象构造的副本。
【解决方案2】:

这是一个小问题

谁能解释一下三个析构函数的原因?

当你打电话时

o=hi();

你的函数被调用,它创建了一个 Entity 类型的对象,作为回报,它调用了构造函数。 这是你得到一个额外的构造函数消息的地方

替换你的Entity(int t) contructor by this

 Entity(int t)
   :a(t)
  {
    std::cout << "Constructor created with integer "<< a << std::endl;
  }

运行代码时,您将看到调用了哪些构造函数。

【讨论】:

  • 所以复制构造函数创建了具有主函数范围的临时对象(具有来自 hi() 中对象的值)。并将临时对象中的值复制到 object(o) 中?
  • 不,@Bubeshp。记住类 A 的复制构造函数的格式是 A(A&) 这意味着你是通过引用传递的。所以这里没有复制。把它想象成你有一个 A 类的对象,比如 obj1,它有一些值 n。现在稍后您想将此值分配给新创建的 obj(例如 obj2)。你可以做的是A obj2 = obj1。这将调用方法 A(A& obj1) 并且您编写的复制构造函数中的任何代码都将被执行。因此,如果您没有将值从 obj1 分配给 obj2 的代码,那么您将不会复制它。记住它只是调用复制构造函数
  • @Bubeshp 观察从 hi 返回的实体 oi;所以 o=hi();变成o=oi;并调用先前的注释复制构造函数。
  • 所以只有两个对象?
  • 是的,只创建了两个对象。但是你在创建对象 o(1) 、 oi(3) 和复制构造函数时调用了 2 次 o = hi();
猜你喜欢
  • 2011-04-11
  • 1970-01-01
  • 1970-01-01
  • 2013-09-25
  • 2013-06-11
  • 2012-07-28
  • 2011-04-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多