当我在boost.python中调用指针作为参数的python函数时,析构函数中存在一些问题。 以下是示例代码
C ++
#include <boost/python.hpp>
#include <boost/python/module.hpp>
#include <boost/python/def.hpp>
#include <string>
#include <iostream>
using namespace boost::python;
class A {
public:
A() {
std::cout<< "A start"<<std::endl;
}
~A() {std::cout<< "A end" <<std::endl;}
}
class B {
public:
B() { aa=new A; }
~B() { delete aa; }
void run(object ct) {
_obj=ct(); //creat a python object
_obj.attr("fun1")(aa); //call a function named "fun1" with a pointer arg
_obj.attr("fun2")(aa); //call a function named "fun2" with a pointer arg
}
A *aa;
object _obj;
}
BOOST_PYTHON_MODULE(ctopy)
{
class_<A> ("A",init<>())
;
class_<b> ("B",init<>())
.def("run",&B::run)
;
}
蟒:
import ctopy
class tc:
def fun1(self,tt):
print "fun1"
def fun2(self,tt):
print "fun2"
bb=ctopy.D()
bb.run(tc)
这个结果:
A start
fun1
A end
fun2
A end
A end
“A end”已打印三次。我在“valgrind”中尝试,有一些错误。我只想运行析构函数一次。怎么办?
答案 0 :(得分:2)
要了解真正发生的事情,你就错过了一个复制构造函数:
B()
A()
B::run()
A(a) <- copy construct A to pass by value
fun1() <- arg passed by value
~A() <- delete copy
A(a) <- copy construct A to pass by value
fun2() <- arg passed by value
~A() <- delete copy
~B()
~A()
在您的示例中,aa
按值传递,即副本的来源。如果aa
是否为指针并不重要,boost会将其转换为传递给python方法的对象。
如果您想避免使用A
的其他副本,则可以通过引用而不是按值传递aa
:
_obj.attr("fun1")(boost::ref(aa));
_obj.attr("fun2")(boost::ref(aa));
这将导致:
B()
A() <- constructed once
B::run()
fun1() <- arg passed by reference
fun2() <- arg passed by reference
~B()
~A() <- destroyed once
有关详细信息,请参阅Calling Python Functions and Methods。