我如何移动std :: unique_ptr用于构造函数参数?

时间:2015-08-10 09:20:42

标签: c++ c++11 move-semantics unique-ptr

我的目标是能够创建一个具有来自同一类家族的不同类型成员对象的对象;在Java看起来像这样:

public class Interface {
    public void test();
}

public class MyImpl1 implements Interface {
    @Override
    public void test() {System.out.println("I am impl 1");}
}

public class MyImpl2 implements Interface {
    @Override
    public void test() {System.out.println("I am impl 2");}
}

public class A {
    public A(Interface myinter) {
        _myinter = myinter;
    }

    Interface _myinter;
}

这样我就可以创建一个具有不同实现的对象:

A a(new MyImpl1());

A a(new MyImpl2());

(对不起,如果这段代码中存在语法错误,只是为了解释我想要的内容)

所以,在C ++中,我认为我会用智能指针实现这一点,以便从RAII中受益。因此,我写了this代码:

#include <iostream>
#include <memory>

using namespace std;

struct Interf {
    virtual void test() {cout << "I am Interf" << endl;}
};

struct A {
    A(std::unique_ptr<Interf> e) : _e(std::move(e)) {}

    std::unique_ptr<Interf> _e;

    void test() {_e->test();}
};

struct Impl : public Interf {
    void test() {cout << "I am Impl;" << endl;}
};

int main()
{
    std::unique_ptr<Interf> b(new Impl);

    A a(std::move(b));

    a.test();

    cout << "fine!" << endl;
    return 0;
}
  • 在我看来工作。但是,这是实施它的正确方法,还是有错误或更好的做法?

  • 此外,在此代码中,我不确定是否需要使用std::move两次。这是将unique_ptr传递给构造函数的正确方法吗?

  • 我不明白的另一件事是,如果我从成员初始化列表中删除_e(std::move(e))并放入构造函数中,此代码无法编译;请问有谁可以解释这里发生了什么?

struct A {
    A(std::unique_ptr<Interf> e) {
        _e(std::move(e));
    }
    ...
};

1 个答案:

答案 0 :(得分:2)

std::unique_ptrInterf传递给您b

  • main()e;
  • 中的局部变量
  • A_e的构造函数的参数;
  • A,构建的Interf实例的成员。

完全可以理解,将std::move()实例移到三个不同的指针上需要连续两次b次操作(ee,然后_e到{ {1}})。

稍微偏离主题:C ++ 14鼓励使用std::make_unique。这是C ++ 11。

您的代码绝对正常:)

编辑:

成员变量仅在成员初始化列表中初始化。在构造函数的正文中,_e(std::move(e));意味着将_e的{​​{1}}称为仿函数。

分配到operator ()应该使用_e完成,尽管直接初始化它总是更好。