取消引用从函数返回的shared_ptr

时间:2013-11-05 17:13:21

标签: c++ shared-ptr

我有一个类DevicePointer,它封装了std::shared_ptr<Device>。需要保存指向设备的指针的各种类派生自DevicePointer。在我开始使用shared_ptr之前,DevicePointer具有::Expose()函数,该函数将返回指向设备的原始指针。现在我使用shared_ptr来保存设备指针,我不知道如何返回它。请注意,应该调用::Expose的唯一原因是取消引用指针。

这就是最初的Expose看起来像:

Device * Expose() const  { return MyDevice; }

并将像这样使用:

Device::Expose()->ExecuteFunction(a, b, c);

现在MyDevicestd::shared_ptr<Device>,我不知道如何将其返回以取消引用。显而易见的选择是:

std::shared_ptr<Device> Expose() {
    return MyDevice;
}

但我担心性能,尤其是创建新的临时std::shared_ptr。所以我需要一些方法来说“你可以取消引用这个指针,但你不能复制它”。仍然需要共享原始文件,因为许多对象将保留对它的引用。

我希望我已充分表达了我的问题。感谢。

3 个答案:

答案 0 :(得分:1)

这不会影响性能

Device & Expose() {
    return *MyDevice.get();
}

编辑:

使对象不可复制:

class Device
{

private:
    //compiler will throw errors when copy constructor or = is called in the code
    Device(const Device &)
    {}
    void operator = (const Device &)
    {
    }
};

编辑(2018-09-05):

从c ++ 11开始,您可以显式删除复制构造函数或赋值运算符:

class Device
{
public:
    Device(const Device &) = delete;
    Device& operator = (const Device &) = delete;
};

答案 1 :(得分:1)

(编辑:这里的第一段是指您的原始问题,您在函数中取消引用指针,并返回引用。)

取消引用这样的指针似乎不太安全,因为它将责任放在调用者上以确定操作的安全性而无法看到指针。如果指针为null,则会出错。

因此,我建议您只返回shared_ptr的副本。除非你每秒呼叫数百次,否则性能影响不应该很大。

不幸的是,没有办法阻止复制。无论是返回指针还是引用,调用者都可以轻松地复制。

答案 2 :(得分:1)

如果您的应用程序是多线程的,并且您的对象可以随时以异步方式“销毁”,那么除了返回shared_ptr副本之外别无选择。 如果您确定对象的生命周期,那么您可以返回对shared_ptr的引用。但是在你的代码发布之后,这可能成为屁股的痛苦。使用解除引用的指针(shared_ptr :: get)也是如此,因为将来支持代码变得更加复杂并且对象的生命周期变得难以跟踪时,将非常困难。