没有合适的构造函数可以从“哑指针”转换为“智能指针”

时间:2011-05-25 23:40:25

标签: c++ memory shared-ptr

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>"

如何解决此问题!?

3 个答案:

答案 0 :(得分:4)

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

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

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

答案 1 :(得分:3)

其他人已经在代码的设计错误上肆虐,但不是代码甚至无法编译的真正问题。 shared_ptr有一个接受原始指针的构造函数,但它被标记为explicit,这意味着您必须明确写出要构造shared_ptr实例。您的函数调用尝试的是隐式执行该构造,由于显式关键字而不允许这样做。

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

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

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

// outside of main
void noop_deleter(A*){/*do nothing*/}

 // call...
b.b(shared_ptr<A>(&a, noop_deleter));

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

答案 2 :(得分:0)

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