【发布时间】:2010-01-27 16:59:48
【问题描述】:
所以我在这里可能有一个相当独特的用例,但我认为它应该可以工作 - 但它不能正常工作。
基本上,我有一个使用静态工厂方法 ( create ) 的类,该方法将 shared_ptr 返回给新创建的 类的实例。这个类还有一个虚函数,我想从 python 重写并从 C++ 调用。
也许我的代码比我的话能更清楚地表达思想:
#include <string>
#include <iostream>
#include <boost/python.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace boost::python;
using namespace boost;
//~ Base Class ClassA
class ClassA
: public enable_shared_from_this<ClassA>
{
protected:
ClassA(){}
public:
static shared_ptr<ClassA> create(){ return shared_ptr<ClassA>( new ClassA() ); }
virtual void quack(){ std::cout<<"quacks like a ClassA Base"<<std::endl; }
};
//~ Wrapper for ClassA
struct WrapClassA : public ClassA, wrapper<WrapClassA>
{
static shared_ptr<WrapClassA> create(){ return shared_ptr<WrapClassA>( new WrapClassA() ); }
void quack()
{
std::cout<<"quacking like a Wrapper..."<<std::endl;
if (override f = this->get_override("quack"))
{
std::cout<<"... override found!"<<std::endl;
f();
}
else
{
std::cout<<"... no override found!"<<std::endl;
ClassA::quack();
}
}
void default_quack(){ this->ClassA::quack(); }
};
//~ C++ Call Test
void quack( shared_ptr<ClassA> ptr )
{
ptr->quack();
}
//~ Exposing
BOOST_PYTHON_MODULE(TestCase)
{
def( "quack", &quack );
class_<ClassA, shared_ptr<WrapClassA>, noncopyable>( "ClassA", no_init )
.def( "__init__", make_constructor(&WrapClassA::create) )
.def( "quack", &ClassA::quack, &WrapClassA::default_quack )
;
}
//~ Main
int main()
{
PyImport_AppendInittab( "TestCase", &initTestCase );
Py_Initialize();
boost::python::object main_module((boost::python::handle<>(boost::python::borrowed(PyImport_AddModule("__main__")))));
boost::python::object main_namespace = main_module.attr("__dict__");
boost::python::object testcase_module( (boost::python::handle<>(PyImport_ImportModule("TestCase"))) );
main_namespace["TestCase"] = testcase_module;
FILE* test_file = fopen("test.py", "r");
PyRun_SimpleFile(test_file, "test.py");
fclose( test_file );
std::cin.get();
return 0;
}
这是 test.py 的内容:
print "Testing.."
class Derived( TestCase.ClassA ):
def __init__( self ):
TestCase.ClassA.__init__( self )
def quack( self ):
print( "Quacks like a derived class!" )
Ainst = TestCase.ClassA()
TestCase.quack( Ainst ) #Should print 'Quacks like ClassA Base'
Dinst = Derived()
TestCase.quack( Dinst ) #Should print 'Quacks like a derived class!', but doesn't!
还有输出:
测试中...像 Wrapper 一样嘎嘎作响... ...没有找到覆盖!嘎嘎声 ClassA Base 像 Wrapper 一样嘎嘎作响…… ...没有找到覆盖!嘎嘎声 A类基地
因此,python 中的基类和派生类的行为相同。看起来由于某种原因它没有找到覆盖。我不确定,但这可能与 create() 函数有关。任何想法将不胜感激!
编辑:
在 py 脚本中添加了 pythonquack - 这可以按预期工作:
def pythonquack( Inst ):
print Inst
Inst.quack()
如我所料,为 Ainst 和 Dinst 调用它会说“Quacks like a Base”和“Quacks like a Derived”。所以由于某种原因,覆盖没有被传递回 C++。
【问题讨论】:
-
你好,你会在qauck函数中提供小字语句来打印self的类型和对象吗?这可能会有所帮助。
-
当然,添加 std::cout
-
此外,检查 C++ 中所持有的 Python 对象的类型表明“派生”正在作为“A 类”(基础)进入 C++。