C++ 重新审视智能指针上没有隐式转换的原因

C++ 重新审视智能指针上没有隐式转换的原因,c++,pointers,smart-pointers,unique-ptr,C++,Pointers,Smart Pointers,Unique Ptr,[下面的一个答案是强制在.release()和.get()之间进行选择,遗憾的是,错误的一般建议是只使用.get()] 摘要:这个问题是出于技术原因或行为原因(可能基于经验),为什么智能指针(如unique\u ptr)被剥夺了指针的主要特征,即在预期的位置传递指针的能力(C API) 我已经研究了这个话题,并在下面列举了两个主要的理由,但这些理由似乎都不成立 但我的傲慢并不是无穷无尽的,我的经验也不是如此广泛,以至于不能让我相信我一定是对的 这可能是因为unique\u ptr并没有被设计成

[下面的一个答案是强制在
.release()
.get()
之间进行选择,遗憾的是,错误的一般建议是只使用
.get()
]


摘要:这个问题是出于技术原因或行为原因(可能基于经验),为什么智能指针(如
unique\u ptr
)被剥夺了指针的主要特征,即在预期的位置传递指针的能力(C API)

我已经研究了这个话题,并在下面列举了两个主要的理由,但这些理由似乎都不成立

但我的傲慢并不是无穷无尽的,我的经验也不是如此广泛,以至于不能让我相信我一定是对的

这可能是因为
unique\u ptr
并没有被设计成简单的哑C API指针生命周期管理作为主要用途,当然
unique\u ptr
的拟议开发不会是[,但是
unique\u ptr
声称是“自动ptr应该是什么”(但我们不能用C++98编写)[但这也可能不是auto_ptr的主要用途


我正在使用
unique\u ptr
来管理一些C API资源,并震惊地发现所谓的智能指针根本不起指针的作用

API的我使用expect指针,我真的不想到处添加
.get()
。这一切都让智能指针
独特了

当它被转换为该指针的类型时,
unique\u ptr
不会自动转换为它所持有的指针的当前原因是什么

void do_something(BLOB* b);
unique_ptr<BLOB> b(new_BLOB(20));

do_something(b); 
// equivalent to do_something(b.get()) because of implicit cast
感谢@Yakk提供的宏提示(,)

使用RIP\u ptr=unique\u dptr;
RIP_ptr rip1(RIP_new_位图(“/tmp/test.png”);
不,这是一个我可以使用的智能指针。 *在定义智能指针类型时,我声明了一次
free
函数 *我可以像指针一样传递它 *当作用域终止时,它将被释放

是的,我可以错误地使用API并泄漏自己的引用,但是
.get()
并不能阻止这一点,尽管这会带来不便


也许我应该在里面放一些
const
s,作为对缺乏所有权转移的点头。

我很惊讶在搜索中没有找到的一个答案是
unique\u ptr::release
[

release()
返回指针和
唯一的\u ptr
然后引用
nullptr
,因此很明显,这可以用于将拥有的引用传递给不使用智能指针的API

通过推断,
get()
是传递无主引用的对应函数

作为一对,这些函数解释了为什么不允许自动取消引用;根据被调用函数如何处理指针,编码器被迫使用
.release()
.get()
替换每个指针

因此,编码人员被迫采取明智的行动,选择一种行为或另一种行为,并将遗留代码升级为更明确、更安全的代码

.get()
是一个奇怪的名称,但这个解释对我来说很有意义


可悲的是,如果编码人员的唯一建议是使用
.get()的话,这种策略是无效的代码不知道选择,错过了一个使代码安全和清晰的机会。

认为公平地说有2种方法来编写软件-易用性和安全性。似乎易用性总是以牺牲安全为代价,反之亦然。C++委员会强烈地将C++推向安全和确定的方向。inism。大概他们认为为了便于表达,有更松散的语言可用。我想你是对的。我正在寻找关于必须添加
.get()的视图的信息
在某种程度上是安全的,因为“更安全”的意思是你必须故意做这件危险的事情。你不能通过隐式强制转换(没有经验或疲惫的开发人员可能不会注意到)意外地做这件事如你所知,抓住指针就是拿着手榴弹并拔出大头针。标准局的人认为这是人们应该知道他们在做的事情:-)我不认为有些人会习惯性地走自己的路来危害自己,这是一个令人信服的论点,即我们不应该有安全功能。@Hurkyl问题是即使是Herb Sutter,由于缺乏信息或合理的论据,该功能也带来了一种安全性。简单地要求用户添加
.get()
无处不在本身并不是一种安全性功能。正如我后来了解到的,强迫用户在
.get()
.release()之间进行选择
是程序员增加安全性的一个机会,前提是他们明白这是被迫的选择,但研究表明这一点并不普遍,而且
.get()
确实被盲目使用,并被推荐为更安全的选择。这并不安全;但这一选择是一个安全的机会。
template<typename T, typename D, D F>
class unique_dptr : public std::unique_ptr<T, D> {
    public: unique_dptr(T* t) : std::unique_ptr<T, D>(t, F) { };
    operator T*() { return this->get(); }
    operator void*() { return this->get(); }
};

#define d_type(__f__) decltype(&__f__), __f__
using RIP_ptr = unique_dptr<RIP, d_type(::RIP_free)>;
RIP_ptr rip1(RIP_new_bitmap("/tmp/test.png"));