【问题标题】:Writing a source function in c++11 properly用c++11正确编写源函数
【发布时间】:2011-11-23 09:55: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添加一些移动构造函数,或者两者兼而有之?

【问题讨论】:

标签: c++ c++11


【解决方案1】:

这已经是最优的1,前提是生成了移动构造函数2

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

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


1 好吧....前提是您的类 Foo 完全受益于移动构造。请记住,move 是对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 并非所有编译器都支持这一点(即使它们确实实现了右值引用),因此您可能必须编写

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

【讨论】:

  • 我想这就是我所追求的。谢谢。我不太担心编译器支持 - GCC 在这方面是最新的,其他的将赶上我最终完成项目的时间......
  • 当你做某些事情(比如定义你自己的构造函数)时,编译器生成的构造函数和操作符被禁用也是不值得的。因此,如果您已经完成了这些事情中的任何一项,则需要显式声明其他正常生成的方法。在这些情况下,您可以使用= default 来获取默认实现,如答案中所示。
猜你喜欢
  • 2017-11-13
  • 1970-01-01
  • 2012-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-21
  • 1970-01-01
相关资源
最近更新 更多