我的目标是能够创建一个具有来自同一类家族的不同类型成员对象的对象;在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
:
b
,main()
中的局部变量;e
,A
构造函数的参数;_e
,构造的A
实例的成员。
在三个不同的指针之间 move Interf 实例需要两个连续的 std::move() 操作(b
到e
,然后 e
到 _e
)。
稍微偏离主题:C++14 鼓励使用 std::make_unique
。但这是 C++11。
你的代码绝对没问题:)
编辑:
成员变量仅在成员初始化列表中初始化。在构造函数体内,_e(std::move(e));
表示调用 _e
的 operator ()
,就好像它是一个仿函数。
分配给_e
应该使用_e = std::move(e);
来完成,尽管直接初始化它总是更好。
关于c++ - 我如何 move std::unique_ptr 作为构造函数参数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31915880/