使用移动语义将基类实例推送到子类实例

时间:2014-08-19 07:52:37

标签: c++ c++11

假设我有一个实例化的Base bFooBase的子类。

我想要做的是拥有Foo

的构造函数
class Foo : public Base
{
    Foo(Base b, T otherArg) : Base(b)
    {
        /*ToDo - do something with otherArg*/
    }
}

移动' b'实例到正在构造的Foo的实例。如果Foo的构造失败(例如在我的/*ToDo step*/中),则不应移动b

我可以在C ++ 11中执行此操作吗? (我付不起深刻的副本)。构造函数原型是否需要Foo(Base&& b, T otherArg)

2 个答案:

答案 0 :(得分:2)

是的,你可以:

  • 声明Base类的移动构造函数,以便接受rvalues
  • 使用std::move
  • 移动基本参数

示例:

#include <iostream>
#include <utility>

class Base
{
    public:

    Base() {}

    Base(Base&& b) { std::cout << "Move ctr"; }  
};

class Foo : public Base
{
    public:

    Foo(Base&& b, double otherArg) : Base(std::move(b))
    {
       // ...
    }
};

int main()
{
    Foo(Base(), 2.0);
}

或者

int main()
{
    Base b;
    Foo(std::move(b), 2.0);
}

注意:

  • 对于异常情况下的回滚,您仍然可以在b中保存Base(Base&& b)的状态(当然,在使用它之前),并通过{{1 rollback_move构造函数中的异常情况下的成员函数。

<强> Live demo

答案 1 :(得分:0)

委托构造函数允许我们在执行任何实际构造之前执行参数操作。

class Foo: public Base {
public:
    // note reference parameter
    Foo(Base&& b, T arg)
        // if do_something fails with an exception here,
        // nothing happens to b since we're just initializing
        // references without touching any object
        : Foo(std::move(b), do_something(arg))
    {}

private:
    Foo(Base&& b, final_arg arg)
        // move construction will only happen here once we
        // have examined the original argument to our satisfaction
        : Base(std::move(b))
    {}
};

在检查参数时要非常小心。你可能觉得有必要做一些事情:

Bar(Arg arg)
    : Bar(inspect_argument(arg, this->qux))
{}

在对象正在构建时使用*this是不明智的。确保你知道自己在做什么。