【问题标题】:C++: An object is not deconstructed when returning it?C ++:返回对象时不解构对象?
【发布时间】:2017-12-11 02:42:57
【问题描述】:

有一天,我想知道返回字符串对象时是否存在内存副本。但是,我发现了一件奇怪的事情。当我在函数中返回一个对象时,我希望有一个复制构造来创建一个临时对象作为返回值。所以,我尝试下面的代码。

class Substring: public string
{
public:
    Substring(const char* s)
    :string(s)
    {
    }

    ~Substring()
    {
        cout << "Deconstruct" << endl;
    }
};

Substring foo()
{
    Substring ret("test");
    printf("Inner address: %p\n", ret.c_str());
    return ret;
}

int main()
{
    Substring test = foo();
    printf("Return address: %p\n", test.c_str());
    return 0;
}

正如我所说,我期待Return addressInner address 不同。并且Deconstruct 应该在Inner address 之后打印出来

这是我得到的。当外部变量test 死亡时,ret 似乎被解构,而不是超出其范围的时间!为什么?

Inner address: 0x7ffed3a4cb40
Return address: 0x7ffed3a4cb40
Deconstruct

【问题讨论】:

标签: c++


【解决方案1】:

C++ 有一个叫做省略的东西。

多个对象的生命周期可以一起省略。这意味着虽然乍一看有 3 个子字符串对象(rettest 和匿名返回值),但在省略之后,它们都是同一个对象,具有一个构造和销毁。

省略有各种限制(标准强制和实际),并且在 中,某些形式成为强制。

特别是,几乎总是允许省略纯右值,如果允许,在 C++17 中几乎总是需要。

命名变量可以用纯右值省略,如果返回语句为return var_name;并且类型匹配,则返回值可以用命名局部变量省略。

人们已经为特定类型的省略起名——RVO 和 NRVO——但我发现它们比启发性更令人困惑。

禁用省略是一个坏主意,必须这样做表明您的对象模型与 C++ 的假设格格不入。

【讨论】:

  • 这是一个很好的答案。因为我是新来的,所以我的投票没有出现。我很抱歉。无论如何,非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-30
  • 1970-01-01
相关资源
最近更新 更多