如果可以的话,我会*
从我的代码中删除所有原始指针,因为使用它们可能不是线程安全的,并且设计的意图也不清楚(可选值、所有权等)。然而,有时不使用指针并不容易。例如,我们倾向于在多态类型的容器中使用基类型的指针:
class A : noncopyable { ... };
class B : public A { ... };
std::vector<A*> v;
v.emplace_back(new B);
// temporary container for some operation
std::vector<A*> selected;
if(check())
selected.emplace_back(v.front());
你对上面的代码有什么想说的吗?所有者是谁?是不是共享所有权?这就是为什么我们应该这样做的原因v
:
std::vector<std::unique_ptr<A>> v;
v.emplace_back(make_unique<B>());
现在很明显,v
拥有这些对象,但我仍然不喜欢它selected
有一个原始指针,这使我的设计不直观。查看标准 C++ 库,我认为只有一种类型可以完成这项工作 - std::reference_wrapper:
std::vector<std::unique_ptr<A>> v;
v.emplace_back(make_unique<B>());
// temporary container for some operation
std::vector<std::reference_wrapper<A>> selected;
if(check())
selected.emplace_back(*v.front());
你觉得这段代码怎么样?这是一个好习惯吗?我知道这一点std::ref()
以及std::cref
主要使用模板的地方,但似乎在这里我们也可以使用它来清楚地说明我们的设计意图。我看到的唯一问题是我必须取消引用std::reference_wrapper
,get()
并且没有operator*()
或operator->()
内部有相同的接口,就像在容器中一样unique_ptr
。我应该自己写类似的东西吗?或者也许可以在未来的 C++ 版本中为这种用例扩展 reference_wrapper?请分享您的反馈。
编辑:我更改了代码示例以更好地显示意图。