所以我可能在這裏有一個相當獨特的用例,但我認爲它應該工作 - 但它不能正常工作。Boost :: Python,靜態工廠和繼承
基本上,我有一個類,它使用靜態工廠方法(創建),返回一個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!
和輸出:
測試...像包裝一樣嘎嘎... ...沒有發現重寫!庸醫像 ClassA基地像一個包裝嘎嘎... ...沒有重寫發現! quacks like ClassA Base
因此,python派生的基類和類都是相同的。由於某種原因,它看起來沒有找到覆蓋。我不確定,但這可能與create()函數有關。任何想法將不勝感激!
編輯:
新增pythonquack到PY腳本 - 這個工作過程預計:
def pythonquack(Inst):
print Inst
Inst.quack()
調用它Ainst和Dinst說:「叫聲也像基」,「像一個派生江湖醫生」 ,如我所料。所以出於某種原因,覆蓋不會傳回C++。
嗨,你會在qauck函數中提供小型打印語句來打印自己的類型和對象嗎?這可能有幫助。 – Anycorn 2010-01-27 18:22:05
當然,添加 std :: cout << typeid(* this).name()<< std :: endl; 給嘎嘎函數返回「struct WrapClassA」,並加入 std :: cout << typeid(* ptr).name()<< std :: endl; 返回「struct WrapClassA」。 我很抱歉,如果你的意思是python對象而不是C++對象。 – 2010-01-27 20:46:08
此外,在C++中檢查持有的Python對象的類型表明「派生」正在以C類爲'ClassA'(Base)。 – 2010-01-27 21:06:35