【发布时间】:2011-11-22 20:18:45
【问题描述】:
我想将一个对象的引用存储为一个weak_ptr。在纯 C++ 中,以下工作:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using namespace boost;
struct Empty
{
Empty(){}
};
struct Store
{
weak_ptr<Empty> value;
Store(){};
void setValue(shared_ptr<Empty> v) {
cout << "storing " << v << endl;
this->value = weak_ptr<Empty>(v);
shared_ptr<Empty> v_ok = this->value.lock();
if (v_ok) {
cout << "ok, v has been stored" << endl;
}
}
shared_ptr<Empty> getValue() {
shared_ptr<Empty> p = this->value.lock();
if (p) {
cout << "stored value : " << p << endl;
} else {
cout << "there's nothing here !" << endl;
}
return p;
}
};
int main()
{
shared_ptr<Empty> e(new Empty);
shared_ptr<Store> st(new Store);
st->setValue(e);
st->getValue();
return 0;
}
编译并运行它会给你这个:
%> ./a.out
storing 0x8c6c008
ok, v has been stored
stored value : 0x8c6c008
现在,如果我用 boost python 封装它:
#include <iostream>
#include <boost/shared_ptr.hpp>
#include <boost/python.hpp>
#include <boost/weak_ptr.hpp>
using namespace std;
using namespace boost;
using namespace boost::python;
struct Empty
{
Empty(){}
};
struct Store
{
weak_ptr<Empty> value;
Store(){};
void setValue(shared_ptr<Empty> v) {
cout << "storing " << v << endl;
this->value = weak_ptr<Empty>(v);
shared_ptr<Empty> v_ok = this->value.lock();
if (v_ok) {
cout << "ok, v has been stored" << endl;
}
}
shared_ptr<Empty> getValue() {
shared_ptr<Empty> p = this->value.lock();
if (p) {
cout << "stored value : " << p << endl;
} else {
cout << "there's nothing here !" << endl;
}
return p;
}
};
BOOST_PYTHON_MODULE (test)
{
class_< Empty, shared_ptr<Empty> >("Empty");
class_< Store, shared_ptr<Store> >("Store")
.def("get",&Store::getValue)
.def("set",&Store::setValue);
}
现在是一个小的 python 脚本来尝试一下
from test import *
e = Empty()
st = Store()
st.set(e)
st.get()
... 结果是...
storing 0x9eb2a18
ok, v has been stored
there's nothing here !
所以很明显,当我仍然使用相同的方法 (setValue) 时,检索一个没有问题 来自 Store::value 的 shared_ptr。但是,一旦我摆脱了这种情况,就什么都没有了!
这怎么可能? python 是否将一个全新的(且无用的)shared_ptr 作为参数传递给 setValue,然后在调用结束时将其销毁?我迷路了。
【问题讨论】:
-
嗯...向
Empty添加一个析构函数,打印一条消息并查看它是否被销毁。另外,如果您存储shared_ptr会发生什么? -
我的猜测是,在一个位置
shared_ptr指的是::boost::shared_ptr,而在另一个位置它指的是::std::shared_ptr。我非常喜欢使用typedef从不同的命名空间中提取名称,而不是使用多个using namespace声明。
标签: c++ boost boost-python