正确编写c ++ 11中的源函数

时间:2011-11-23 09:55:12

标签: c++ c++11

我的头疼了:我已经阅读了很多关于C ++ 11x移动语义的博客,我的大脑已经糊涂了,所以请有人给我一个关于如何使下面的代码有效工作的简短而又甜蜜的指南吗?给定一个类Foo,我希望能够编写在不同状态(有时称为源函数)返回Foo个对象的函数,并尽可能高效地执行此操作。

class Foo {
    // Some methods and members
};

Foo getFirstFoo() {
    Foo foo;
    // Do some things to foo
    return foo;
} 

Foo getSecondFoo() {
    Foo foo;
    // Do some different things to foo
    return foo;
} 

int main() {
    Foo f = getFoo();
    // use f ...
    f = getSecondFoo();
    // use f ...
    return 0;
}

我不想修改Foo,并且想法是允许通过各种非成员源函数创建各种Foo对象,因此添加更多构造函数会错过这一点。

在C ++ 03中,我的选择是将返回的对象包装在auto_ptr中(一个很大的缺点是收件人代码需要知道处理智能指针),或者交叉我的手指和希望可能会发生某种优化(可能是main中的第一行,第二行可能更少)。 C ++ 11x似乎通过移动语义提供了更好的东西,但我如何利用它们呢?所以我需要在源函数中更改对象返回的方式,或者将一些移动构造函数添加到Foo,或者两者都添加?

1 个答案:

答案 0 :(得分:6)

这已经是最优的 1 ,只要生成移动构造函数 2

class Foo {
    public: 
        Foo(Foo&&) = default;
        Foo& operator=(Foo&&) = default;
};

默认情况下,返回值是右值引用。


1 嗯....只要您的Foo课程完全受益于移动建设。请注意, 移动 copy 的优化。有些副本无法改进!例如,不适合:

struct Foo  { int data; };
struct Foo2 { int data[5<<10]; };

非常适合:

struct Foo3 { std::vector<std::string> data; };

有关此类内容的更一般背景信息,请参阅Move semantics - what it's all about?


2 并非所有编译器都支持它(即使他们 实现 rvalue references ),因此您可能必须编写< / p>

  • 移动构造函数
  • 移动作业