以下代码无法在Visual C ++ 11中使用此错误进行编译:
1> c:\ users \ tony \ documents \ visual studio 11 \ projects \ cpp11_ex1 \ cpp11_ex1 \ main.cpp(52):错误C2440:'':无法从'Foo * const'转换为'std ::的weak_ptr< _Ty>'
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( weak_ptr<Foo> foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
weak_ptr<Foo> _foo;
};
class Foo
{
public:
Foo() : _bar() { _bar = make_shared<Bar>( weak_ptr<Foo>(this) ); printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}
似乎我无法从原始weak_ptr
指针创建this
。这引起了一系列有趣的问题。
由于我在Foo
的ctor中尝试此操作,Foo
的引用计数为0(即main中的make_shared<>
尚未返回)。< / p>
我发现我可以从 weak_ptr
创建shared_ptr
s ...但是如果我改变Bar
ctor采取shared_ptr
,我调用Bar
的构造函数的行为最终会破坏Foo
! (由于Foo
的引用计数仍为0,因此通过调用shared_ptr
的ctor创建(然后销毁)Foo
到Bar
。
我真正想做的就是创建Foo
,创建Foo
并拥有一个Bar
,但让Bar
变弱引用回Foo
。我真的不想被迫进入2部分初始化!
答案 0 :(得分:2)
boost::weak_ptr<T>
用于存储,而不是用于。
您希望传递boost::shared_ptr
个对象,然后将它们存储在boost::weak_ptr
个对象(通常是私有的)中。
struct Foo {
Foo(const boost::shared_ptr<int> &data) : weak_data(data) {}
boost::shared_ptr<int> getData() {
boost::shared_ptr<int> data = weak_data.lock();
if (!data)
throw std::runtime_error("data is no longer valid");
return data;
}
private:
boost::weak_ptr<int> weak_data;
};
无论你是扔还是回传,空shared_ptr<T>
取决于你。如果你不能锁定对象,你不应该再传递它。那时它真的无效。
话虽如此,您可能希望避免以这种方式创建共享指针。您的示例中不清楚您是否需要此设计。如果你可以像Mooing Duck这样的方式重新设计它,那么你会更加诚实。
从类似的经验来看,当我需要像这样的循环依赖时,它可能不是一个简单的构造场景。我会看一个两部分构造函数(静态命名构造函数,或者也许是构建器)来管理创建两个对象并确保它们的引用是有效的。
以下是一个简单命名构造函数的快速示例。
class Foo;
// Likely that this should be a child class of Foo
class Bar {
private:
friend class Foo;
Bar(const boost::shared_ptr<Foo> &foo) : weak_foo(foo) {}
weak_ptr<Foo> weak_foo;
};
class Foo {
public:
static boost::shared_ptr<Foo> CreateFoo() {
boost::shared_ptr<Foo> foo = boost::shared_ptr<Foo>(new Foo);
foo.bar = boost::make_shared<Bar>(foo);
return foo;
}
private:
Foo() {}
boost::shared_ptr<Bar> bar;
};
在这里,您可以控制正确创建foo
和bar
变量的不变量。
答案 1 :(得分:0)
根据定义,在没有指向同一对象的强指针的情况下,不可能有一个弱指针。当最后一个强指针消失时,所有弱指针都变为空。这就是所有弱点。
编写自己的函数,将共享ptr返回给Foo(Foo工厂),并从该指针初始化Bar中的弱ptr。
答案 2 :(得分:0)
由于shared_ptr将指向Foo
,并且Bar将始终由Bar的shared_pointer拥有,因此如果Bar存在,则Foo存在。因此,你不需要Bar中的智能指针。 (如果我理解正确的问题)
#include <stdio.h>
#include <memory>
using namespace std;
class Foo;
class Bar
{
public:
Bar( Foo* foo ) : _foo(foo) { printf("Bar(%p)\n",this); }
~Bar() { printf("~Bar(%p)\n",this); }
private:
Foo* _foo;
};
class Foo
{
public:
Foo() : _bar(new Bar(this)) { printf("Foo(%p)\n",this); }
~Foo() { printf("~Foo(%p)\n",this); }
private:
shared_ptr<Bar> _bar;
};
int main( int argc, char* argv[] )
{
shared_ptr<Foo> instance = make_shared<Foo>();
return 0;
}