如果可以的话,我会*从我的代码中删除所有原始指针,因为使用它们可能不是线程安全的,并且设计的意图也不清楚(可选值、所有权等)。然而,有时不使用指针并不容易。例如,我们倾向于在多态类型的容器中使用基类型的指针:
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?请分享您的反馈。
编辑:我更改了代码示例以更好地显示意图。