【问题标题】:Smart pointers cannot be used as raw pointers automatically?智能指针不能自动用作原始指针吗?
【发布时间】:2019-05-30 08:33:02
【问题描述】:

我正在尝试将代码转换为使用智能指针而不是原始指针。但是想知道 - 智能指针真的不可能用作原始指针吗?

在这个例子中:

#include <iostream>
#include <string>
#include <memory>

void printer(int* x)
{
    std::cout << "x = " << x << std::endl;
}

int main()
{   
    auto x = std::make_unique<int>(5);
    printer(x);
    return 0;
}

我收到一个错误:

In function 'int main()': 14:14: error: cannot convert
'std::unique_ptr<int, std::default_delete<int> >' to 'int*' for argument '1'
to 'void printer(int*)' 

这应该如何编码?谢谢!

【问题讨论】:

  • 您需要printer(x.get()); 才能访问后面的原始指针。出于充分的理由,这不是自动完成的。
  • @πάνταῥεῖ 出于极其主观的原因,它并没有隐含地完成:“原始”ptr 是“不安全的”。允许它们没有固有的问题。并且说当你继续使用 ptr 时允许转换为 ptr 太危险了,这从根本上是矛盾的。
  • @MichaelDoubez "如果允许隐式转换为 *,将静默编译 -- urk" 说隐式转换允许更多程序编译是微不足道的,但不能令人信服争论。
  • @curiousguy 智能指针都是关于所有权语义的,包装指针在这方面是二等公民。您可以期望而不是 get() 的最好方法是隐式转换为 std::weak_ptr&lt;T&gt;

标签: c++ pointers smart-pointers implicit-conversion language-design


【解决方案1】:

不可能有隐式转换,因为隐式转换没有上下文来做正确的事情。 printer 采用非拥有指针,但其他需要拥有所有权的函数呢?比如

void kill(int *p) { delete p; }

在调用kill(p); 时默默地进行转换是错误的!这将导致双重删除。指针无法知道它应该停止拥有该对象,它必须通过调用release 来告知。其他任何事情都是错误的。

由于智能指针都是关于强制执行显式所有权语义,因此转换为原始指针也需要显式,并且具有传达所有权受到影响的名称。

【讨论】:

  • 显然所有权的转移需要明确(除了从右值移动副本)。
  • 对于标准指针类型,您应该提及 get()release()
  • @curiousguy 打错字了,我的意思是get()
【解决方案2】:

std::make_unique&lt;&gt;() 返回一个std::unique_ptr,这使得变量x 的类型为std::unique_ptr&lt;int&gt;。这些智能指针不仅仅是原始指针,您不能像原始指针一样使用它们。您应该改为使用 x 上的 get() 方法来获取它所指向的 int*

【讨论】:

  • 那将是反对在语言中进行隐式转换的论据。
猜你喜欢
  • 2016-08-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-25
  • 2022-01-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多