【问题标题】:c++ simple allocation by a functionc++ 通过函数进行简单分配
【发布时间】:2012-05-11 12:30:53
【问题描述】:

我试图了解这种分配在 c++ 中是如何工作的:

Test other = toto();

这是完整的代码源:

#include <iostream>

class Test
{
public:
    Test()
    {
        j = i++;
        std::cout<<"default constructor "<<j<<std::endl;
    }

    Test(const Test&)
    {
        std::cout<<"constuctor by copy "<<j<<std::endl;
    }
    Test & operator=(const Test&)
    {
        std::cout<<"operator = "<<j<<std::endl;
        return *this;
    }
    int j;
    static int i;
};

int Test::i = 0;

Test toto()
{
    Test t;
    return t;
}

int main()
{
    Test other = toto();
    std::cout<<other.j<<std::endl;
    Test another;
    return 0;
}

代码没有通过复制或操作符=使用构造函数,所以我真的不明白它是如何工作的...... 我用的是 gcc 4.7.0

感谢您的帮助:)

杰罗姆

【问题讨论】:

  • @jrok - 从常见问题解答中“他们的一位工程师告诉我,他们发现这种按值返回的优化非常快,即使您没有在打开优化的情况下进行编译,您也可以得到它“所以显然这不一定是真的。它可能因编译器而异。
  • @Benj 确实,在尝试使用 gcc 时,即使没有优化也没有副本。

标签: c++ allocation


【解决方案1】:

格式语义:

Test other = toto();

涉及多个副本(但没有分配)。允许编译器 然而,省略了所有不同的实例,这消除了 副本;几乎所有的编译器都会做这种优化。

更具体地说,标准没有指定类类型的值在哪里 被返回,但通常的解决方案是让调用者分配 空间,并将指向它的隐藏指针传递给函数。没有 上面提到的优化:

Test
toto()
{
    Test t;
    return t;
}

将导致构造局部变量t,然后 return 语句会将t 复制到 hidden 指向的空间中 指针。优化(称为命名返回值优化,或 NRVO) 这里导致编译器使用由 t 的隐藏指针,而不是在本地创建单独的 t。 (显然,当它这样做时,它不会破坏t,因为它会 否则在复制之后。)

在声明中:

Test t = toto();

,形式语义会让编译器为一个 临时类型的Test,传递这个空间的地址作为隐藏 指向toto 的指针,然后将此临时复制到t 并销毁它。 这里的优化在于编译器传递的地址 t 直接到toto,省略中间临时。

【讨论】:

    【解决方案2】:

    看看return value optimisation,这是避免构造函数调用的常见优化。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-01-14
      • 2014-02-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-06
      • 2012-07-21
      相关资源
      最近更新 更多