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

bel*_*daz 4 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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

seh*_*ehe 6

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

class Foo {
    public: 
        Foo(Foo&&) = default;
        Foo& operator=(Foo&&) = default;
};
Run Code Online (Sandbox Code Playgroud)

返回值默认为右值引用.


1嗯....前提是您的Foo课程完全受益于移动建筑.请记住,移动复制的优化.有些副本无法改进!例如,不适合:

struct Foo  { int data; };
struct Foo2 { int data[5<<10]; };
Run Code Online (Sandbox Code Playgroud)

非常适合:

struct Foo3 { std::vector<std::string> data; };
Run Code Online (Sandbox Code Playgroud)

请参阅移动语义 - 它的全部内容?有关此类事情的更一般背景.


2并非所有的编译器都支持,但(即使他们这样做实现右值引用),所以你可能会写

  • 移动构造函数
  • 移动任务