Pointers C++;11当有一个所有者(std::uniqueptr)但其他对象需要一个";“处理”;到目标了吗?
在以下情况下,我似乎发现了很多代码:Pointers C++;11当有一个所有者(std::uniqueptr)但其他对象需要一个";“处理”;到目标了吗?,pointers,c++11,Pointers,C++11,在以下情况下,我似乎发现了很多代码: class Thing { public: Thing() = default; }; class Repo { public: Repo() { // Makes things.. mThings.emplace_back( std::make_unique<Thing>() ); } // I find I need functions like this, // a function w
class Thing
{
public:
Thing() = default;
};
class Repo
{
public:
Repo()
{
// Makes things..
mThings.emplace_back( std::make_unique<Thing>() );
}
// I find I need functions like this,
// a function which may return some record,
// or might return nullptr if there is no record.
Thing* GetThing(int id)
{
// Might return nullptr, or might return
return mThings[0].get();
}
private:
std::vector<std::unique_ptr<Thing>> mThings;
};
是的,纯指针就足够了。但是具有指向
对象的句柄(指针)的对象必须假定所指向的对象将比它们更长寿。有a和a,它们的作用与您需要的类似:
// make sure to include <boost/optional/optional.hpp>
boost::optional<Thing&> GetThing(int id)
{
// Might return nullptr, or might return
return boost::optional<Thing&>(*mThings[0]);
}
(可以直接使用指针之类的东西;我没有测试过,我是从文档中构建的)
注意:我不完全确定即将发布的std::optional
是否支持引用。他们。不过,这里使用引用有点重要,因为正如OP在对问题的评论中所指出的,在这里使用裸类型将导致复制,而使用原始指针作为T将有点违背目的
@JohannesD评论了一个指向的链接,该链接正是为此目的制作的。不过,我没有关于该草案状态的信息
然而:现在,我仍然倾向于在这种情况下使用原始指针,主要是因为std::optional
还没有实现(甚至没有完全指定,可能根本不支持引用)。我也有点失望,因为它已经从C++14中删除了
确保在该函数的文档中明确说明接收方不拥有所有权。在我看来,只要您不想将代码与多线程一起使用,这是可以接受的/OK。如果您将来可能想添加多线程,这将是一个真正的问题,因为调用方无法知道返回指针的有效时间,因为另一个线程可能会执行使指针无效的操作。在这种情况下,std::shared\u ptr
更有意义(无论是在数据结构中还是作为返回值)。optional
将是一个选项(双关语),但这尚未影响STL实现。在这些情况下,我返回原始指针。但是我没有任何权威的来源来回答这个问题……你能发布一个答案来解释这个东西是什么,以及如何在我的例子中使用它吗?我刚才查看了boost文档,但不确定它是否适合?它不会导致复制对象等吗?可选
似乎合适,但允许api用户使用生命周期语义可能有点奇怪。std::shared_ptr
。很抱歉,这与多线程无关。一个对象比另一个对象先被删除的原因有很多<代码>标准::共享_ptr
不适用于高性能代码。当所有权真正共享时,应该很少使用它。不是作为数据竞争的解决方案。@JonasWielicki:以什么方式?规范保证(该页面建议但并未真正涵盖)如果一个对象的最后两个共享\u ptr被两个不同的线程破坏,那么正好有一个线程会看到refcnt下降到0并破坏该对象。如果多个执行线程在不同步的情况下访问同一共享\u ptr引用的对象,除非使用原子函数的共享ptr重载,否则可能会发生数据竞争。再次阅读,这实际上可能指同一线程访问的单个共享std::shared_ptr
对象。在这种情况下,它可能不会影响API,假设在传递它时复制了一个副本。@JonasWielicki,CPPPreference页面的措辞非常糟糕。shared\u ptr
的原子操作不会阻止“被[…]shared\u ptr
引用的对象”上的数据争用,只会在shared\u ptr
本身上争用。我认为这是在试图说,当多个线程不同步地访问同一个共享的\u ptr
并且至少有一个线程使用一个非常量成员函数时,就会出现数据竞争,但这很难说。它似乎试图在一句话中谈论两件不同的事情。另一个被提议的替代方案是@JohannesD,听起来它是为这种情况而设计的。你对这篇论文的现状有什么看法吗?没有,除了它已经经过了三次修订之外,至少它看起来还很有活力:)在:“对于引用类型,或者对于可能的cv限定类型,需要实例化模板可选,就地或空选的程序是格式错误的。“如果我回忆起关于标准提案邮件列表的讨论,我认为对于optional
的确切语义应该是什么缺乏共识。我从cppreference.com网站上怀疑这样的事情,但是boost::optional支持它。我将修改我的答案a,使之更清楚。
// make sure to include <boost/optional/optional.hpp>
boost::optional<Thing&> GetThing(int id)
{
// Might return nullptr, or might return
return boost::optional<Thing&>(*mThings[0]);
}
Repo someRepo;
boost::optional<Thing&> someThing = someRepo;
if (someThing) {
// use someThing just like a pointer
} else {
// do not touch the value
}