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>"
如何解决此问题!?
答案 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);
...
}