2011-05-25 69 views
0
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); 
} 

所以我得到了这个错误,抱歉,这是我的智能指针的第一次!没有合适的构造函数存在将“哑指针”转换为“智能指针”

错误:

no suitable constructor exists to convert from "A *" to "std::tr1::shared_ptr<A>"

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

+0

那是什么'B(void)'? – 2011-05-25 23:42:42

+0

我的猜测是一个构造函数 – 2011-05-25 23:45:26

+0

B(void)ctor !!!? – Abanoub 2011-05-25 23:46:51

回答

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

而实际上有一个使用了这一点,如果你有一个库的API,绝对想要一个shared_ptr但你想叫它与一个堆栈变量。该API的设计是另一回事...

4

智能指针的全部要点是拥有所有权。也就是它是负责释放它所指向的任何内容。试图告诉它管理已经由完全不同的系统管理的事情是毫无意义的。

在你的情况下,a已被自动管理,你为什么想要由智能指针管理?即使这样做,你只是设置自己删除它两次,这是UB。

要么给它拥有一些东西,如new A(1),或更改b以对它不拥有的东西进行操作。

+0

“拥有所有权”......它在很大程度上取决于智能指针的类型,基本上使所有所有权策略之间的分歧对于正确理解智能指针是强制性的。与shared_ptr我们有共享所有权,与auto_ptr我们有严格的所有权的一个实体瓦特/所有权转让复制,等 – 2011-05-25 23:53:16

+0

@AlexandreAbreu:我明白,你只是选择的特定措辞的措辞,但我认为他的更重要的一点是,给任何智能指针分配堆栈中的对象的地址将导致UB。 – ildjarn 2011-05-26 00:01:23

+0

@亚历克斯:是的,在每种情况下,他们都拥有自己的资源,因此“拥有所有权”。他们管理这种所有权的各种方式与前面的陈述无关。 – GManNickG 2011-05-26 00:09:22

0

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

的std :: shared_ptr的(pMyA)

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

像这样的事情会是一个更好的使用情况:

class B 
{ 
    void b (shared_ptr <A> pA) {} 
} 

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