如果我有
//test.hpp
class iA
{
public:
virtual ~iA(){}
virtual void foo() const = 0;
};
class A1 : public iA
{
public:
virtual ~A1(){}
A1(){}
virtual void foo() const;
};
class A2 : public iA
{
public:
virtual ~A2(){}
A2(){}
virtual void foo() const;
};
class B
{
public:
B(int a);
B(const std::string& s);
~B() {if (a_) {delete a_; a_ = 0;}}
const iA& a() const
{
return *a_;
}
void foo() const;
private:
iA* a_;
};
我在下面编写了python包装器:
struct iAWrap : iA, boost::python::wrapper<iA>
{
void foo() const
{
this->get_override("foo");
}
};
BOOST_PYTHON_MODULE(libtest)
{
using namespace boost::python;
def("greet", greet);
class_<iAWrap, boost::noncopyable>("iA")
.def("foo",pure_virtual(&iA::foo))
;
class_<B>("B",init<int>())
.def(init<std::string>())
.def("foo", &B::foo)
.def("a", &B::a, return_internal_reference<1>())//line I have a question about
;
}
return_internal_reference&lt; 1&gt;将返回的A引用的生命周期绑定到B的不可见“self”参数
答案 0 :(得分:1)
它一直帮助我把它想象成被返回的对象(A
)扩展它的拥有对象(B
)的生命周期至少只要返回的对象(A
)。
return_internal_reference
文档描述了owner_arg
:
包含要返回引用或指针的对象的参数的索引。如果用于包装成员函数,则参数
1
是目标对象(*this
)。
在原始代码中,owner_arg
显式设置为1
,表示成员函数中的this
对象(B
)(&B::a
) invocation是包含返回对象(iA
)的对象。
with_custodian_and_ward_postcall
记录了终身行为效应,其中指出:
ward 对象在保管人 [...]
之后才会销毁
return_internal_reference
文档的类概要简化了实际的继承链:
template <std::size_t owner_arg = 1, class BasePolicy_ = default_call_policies>
struct return_internal_reference
: with_custodian_and_ward_postcall<0, owner_arg, BasePolicy_>
{
// ...
};
return_internal_reference
结构:
0
作为custodian
,将iA
的返回对象(postcall()
)设置为关系中的保管人。 / LI>
owner_arg
(return_internal_reference
默认值设置为1
)作为ward
,将*this
对象(B
)设置为<在关系中他们 。因此,在B
保管人对象之后,iA
ward 对象才会被销毁。
以下是演示此行为的完整简单示例:
#include <iostream>
#include <boost/python.hpp>
class Foo
{
public:
Foo() { std::cout << "Foo()" << std::endl; }
~Foo() { std::cout << "~Foo()" << std::endl; }
};
class Bar
{
public:
Bar() { std::cout << "Bar()" << std::endl; }
~Bar() { std::cout << "~Bar()" << std::endl; }
Foo& foo() { return foo_; }
private:
Foo foo_;
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
python::class_<Foo>("Foo");
python::class_<Bar>("Bar")
.def("foo", &Bar::foo, python::return_internal_reference<>())
;
}
Interactive Python:
>>> import example
>>> bar = example.Bar()
Foo()
Bar()
>>> foo = bar.foo()
>>> del bar
>>> del foo
~Bar()
~Foo()
请注意,bar
ward 对象的生命周期至少与foo
保管人对象一样长。