C++ 取消引用从函数返回的共享\u ptr

C++ 取消引用从函数返回的共享\u ptr,c++,shared-ptr,C++,Shared Ptr,我有一个类,DevicePointer,它封装了一个std::shared\u ptr。需要保存指向设备指针的各种类派生自DevicePointer。在我开始使用shared\u ptr之前,DevicePointer有一个::Expose()函数,该函数将返回指向设备的原始指针。现在我使用shared_ptr来保存设备指针,我不知道如何返回它。请注意,应该调用的唯一原因是取消对指针的引用 这就是原始曝光的样子: 并且会这样使用: 现在,MyDevice是一个std::shared\u ptr,

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

这就是原始曝光的样子:

并且会这样使用:

现在,
MyDevice
是一个
std::shared\u ptr
,我不知道如何返回它以取消引用。显而易见的选择是:

std::shared_ptr Expose(){
返回我的设备;
}
但我担心性能,尤其是创建新的临时
std::shared\u ptr
。所以我需要说“你可以取消引用这个指针,但是你不能复制它”。原始文件仍然需要共享,因为许多对象将保留对它的引用


我希望我已经充分阐述了我的问题。谢谢。

这不会影响性能

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;
};

这不会影响性能

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;
};
(编辑:这里的第一段提到了您的原始问题,在这里您取消了对函数中指针的引用,并返回了一个引用。)

这样取消对指针的引用似乎不太安全,因为它让调用者有责任在看不到指针的情况下确定操作的安全性。如果指针为null,它将出错

因此,我建议只返回一份
shared\u ptr
的副本。除非每秒调用数百次,否则性能影响不会很大

不幸的是,没有办法阻止复制。无论您是返回指针还是引用,调用方都可以轻松获取副本。

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

这样取消对指针的引用似乎不太安全,因为它让调用者有责任在看不到指针的情况下确定操作的安全性。如果指针为null,它将出错

因此,我建议只返回一份
shared\u ptr
的副本。除非每秒调用数百次,否则性能影响不会很大


不幸的是,没有办法阻止复制。无论您返回指针还是引用,调用方都可以轻松获取副本。

如果您的应用程序是多线程的,并且您的对象可以在任何时候以异步方式“销毁”,那么除了返回共享副本之外,别无选择。
若您确定对象的生存期,那个么可以返回对共享\u ptr的引用。但这可能会成为你的代码发布后的麻烦。取消引用的指针(shared_ptr::get)也是如此因为将来当代码变得更加复杂,对象的生命周期变得难以跟踪时,将很难支持该代码。

如果您的应用程序是多线程的,并且您的对象可以在任何时候以异步方式“销毁”,那么除了返回共享副本之外,别无选择。
若您确定对象的生存期,那个么可以返回对共享\u ptr的引用。但这可能会成为你的代码发布后的麻烦。取消引用指针(shared_ptr::get)也是如此,因为将来当代码变得更加复杂,对象的生命周期变得难以跟踪时,将很难支持该代码。

请澄清您的问题。函数
Device&Expose()
没有返回原始指针,而是返回引用。如果要从共享指针访问基础指针,可以使用
get
方法(cf.)。确定,编辑为不太含糊。现在是关于只返回指针的问题。我更新了答案,解释了如何防止MyDevice不复制。我可以问一下为什么需要公开底层指针吗?也就是说,为什么需要这样做:
Device::Expose()->ExecuteFunction(a,b,c)
,而不是简单地按如下方式执行:
Device->ExecuteFunction(a,b,c)
?请注意,
std::shared\u ptr
将正确处理
->
操作员。请澄清您的问题。函数
Device&Expose()
没有返回原始指针,而是返回引用。如果要从共享指针访问基础指针,可以使用
get
方法(cf.)。确定,编辑为不太含糊。现在是关于只返回指针的问题。我更新了答案,解释了如何防止MyDevice不复制。我可以问一下为什么需要公开底层指针吗?也就是说,为什么需要这样做:
Device::Expose()->ExecuteFunction(a,b,c)
,而不是简单地按如下方式执行:
Device->ExecuteFunction(a,b,c)
?请注意,
std::shared\u ptr
将正确处理
->
运算符。这里不需要调用
.get()
。我想就是这样(减去.get())。除了彼得所说的不能阻止打电话的人抄袭。嗯,是的,你是对的,不需要调用
get
,我通常避免不调用它,这样其他程序员就知道
MyDevice
是一个共享/侵入式ptr。这里不需要调用
.get()