没有合适的构造函数可以从"dumb pointer"转换为"smart pointer"

No suitable constructor exists to convert from "dumb pointer" to "smart pointer"

本文关键字:pointer dumb 转换 smart 构造函数      更新时间:2023-10-16
struct A
{
    A(int a);
};
struct B
{
    B();
    void b(std::shared_ptr<A> a);
};
int main()
{
    A a(1);
    B b;
    b.b(&a);
}

所以我犯了这个错误,对不起,伙计们,这是我第一次用智能指针!!

错误:

没有合适的构造函数可以从"A *"转换为"std::tr1::shared_ptr<A>"

我该如何解决这个问题!?

智能指针的全部意义在于拥有所有权。也就是说,它负责释放它指向它的任何东西。试图告诉它管理已经由一个完全不同的系统管理的东西是没有意义的。

在您的情况下,a已经被自动管理,为什么您希望由智能指针管理?即使这样做有效,你也只是设置自己删除两次,这就是UB。

要么给它一些拥有的东西,比如new A(1),要么更改b来操作它不拥有的东西。

其他人已经对你的代码的设计错误大声疾呼,但不是真正的问题——为什么代码甚至没有编译。shared_ptr有一个接受原始指针的构造函数,但它被标记为explicit,这意味着您必须明确地写出要构造shared_ptr实例的内容。函数调用所尝试的是隐式进行构造,这是不允许的,因为显式关键字。

以下内容将进行编译,但给出未定义的行为,因为shared_ptr将(尝试(delete是一个驻留在堆栈上的对象,因此不可删除:

b.b(shared_ptr<A>(&a)); // explicit construction

shared_ptr的一个特殊特性是,您可以向构造函数传递一个deleter,该deleter将在删除所拥有的指针时被调用。你可以编写并使用一个"noop"deleter,它什么都不做;以下不会调用未定义的行为,也不会尝试删除堆栈变量:

// outside of main
void noop_deleter(A*){/*do nothing*/}
 // call...
b.b(shared_ptr<A>(&a, noop_deleter));

如果你有一个库API,它绝对想要一个shared_ptr,但你想用堆栈变量来调用它,那么这实际上是有用途的。API的设计是另一回事。。。

std::tr1::shared_ptr有一个构造函数,允许向下传递给定的原始指针。所以,如果你有一个指向a的指针,你会做这样的事情:

std::shared_ptr(pMyA(

但在您的情况下,指向A的指针指向一个自动变量,而不是可以在使用后删除的动态分配的内存资源。

像这样的东西将是一个更好的用例:

class B
{
  void b (shared_ptr <A> pA) {}
}
int main ()
{
  shared_ptr<A> pA (new A);
  B b;
  b.b (pA);
  ...
}