c++ - 我如何 move std::unique_ptr 作为构造函数参数?

标签 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));
    }
    ...
};

最佳答案

共有三个 std::unique_ptr 传递您的 Interf :

  • bmain()中的局部变量;
  • eA构造函数的参数;
  • _e,构造的A实例的成员。

在三个不同的指针之间 move Interf 实例需要两个连续的 std::move() 操作(be,然后 e_e)。

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

你的代码绝对没问题:)

编辑:

成员变量仅在成员初始化列表中初始化。在构造函数体内,_e(std::move(e)); 表示调用 _eoperator (),就好像它是一个仿函数。

分配给_e应该使用_e = std::move(e);来完成,尽管直接初始化它总是更好。

关于c++ - 我如何 move std::unique_ptr 作为构造函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31915880/

相关文章:

c++ - 如何创建 RandomAccessStreamReference 来访问 .rc 文件中定义的资源?

c++ - 为什么 cout 的默认精度不影响评估结果?

c# - 如何从 C++ dll 在 C# 函数中传递大小未知的数组?

c++ - 枚举器值的计算结果为 2147483648,无法将其缩小为类型 'int'

c++ - 为什么抛出局部变量调用 move 构造函数?

如果两个模板函数都匹配参数列表,C++ 将调用哪个模板

c++ - 如何用空白字段改进 std::tuple?

android - 在 VS2015 上使用 -std=c++11

c++ - move 语义不完整吗?

c++ - ref-qualifier `const &&` 有什么用?