【问题标题】:How can I know when a temporary object is being created and destructed?我如何知道何时创建和销毁临时对象?
【发布时间】:2014-02-07 16:49:32
【问题描述】:

我如何知道临时对象何时被创建和销毁以及如何创建和销毁?

例如,假设我们有一个名为 Foo 的类 以及一个返回 Foo 对象的函数,其参数是一个对象,以及对一个对象的引用。

Foo func(Foo a ,Foo & b);

在我知道的情况下创建了多少对象?
它是使用复制构造函数创建的还是常规创建的?

【问题讨论】:

  • 您是在谈论new 的内存分配还是类的实例化?你总是可以创建一个自定义的auto_ptr 类。

标签: c++ oop


【解决方案1】:

使用构造函数和析构函数,将打印语句插入其中。

#include <iostream>

class Foo
{
    public:
        Foo(){}
        Foo(const Foo &other) {std::cout<<"A copy was made\n";}
        Foo(Foo &&other) {std::cout<<"Foo was moved\n";}
        ~Foo(){std::cout<<"Destroyed Foo\n";}
};


Foo func(Foo a, Foo &b)
{
    return a;
}

Foo func_const(const Foo &a, Foo &b)
{
    return a;
}

Foo func_temp()
{
    return Foo();
}

int main()
{
    Foo f;
    func(f, f);

    std::cout<<"\n\n\n";

    func_const(f, f);

    std::cout<<"\n\n\n";

    Foo g = func_temp();
}

以上打印(使用ideone):

Foo constructed
A copy was made
Foo was moved
Destroyed Foo
Destroyed Foo



A copy was made
Destroyed Foo



Destroyed Foo
Destroyed Foo

带有函数签名:

Foo func(Foo a, Foo &amp;b),参数a 可以进行复制。编译器的优化也可能会省略副本。参数b 从不复制,因为它是通过引用传递的,通常表示您将修改传递的对象;不修改副本。

当返回一个 Foo 时,它可能会也可能不会返回一个副本。这取决于你的类的定义。见http://en.wikipedia.org/wiki/Return_value_optimization

【讨论】:

  • 将打印语句添加到另一个空构造函数可能会很好地影响调用构造函数的时间和情况(以及创建对象的时间和情况):stackoverflow.com/a/8287110/777186
  • @jogojapan 允许编译器绕过创建对象执行优化,即使构造函数有副作用。
  • @bolov 但只要遵循 as-if 规则,当不允许复制省略时,编译器也可以省略副本。添加打印语句会改变这一点。
  • 是的。你们是对的。我从构造函数中删除了std::cout,并且完全删除了 foo 的构造。不过,这只发生在func_temp 上。其他功能不受影响。
猜你喜欢
  • 1970-01-01
  • 2015-12-11
  • 2015-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-19
  • 2011-03-03
  • 1970-01-01
相关资源
最近更新 更多