Boost :: Python,静态工厂和继承

Jon*_*ott 5 c++ python boost

所以我可能在这里有一个相当独特的用例,但我认为它应该工作 - 但它不能正常工作.

基本上,我有一个使用静态工厂方法(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;
}
Run Code Online (Sandbox Code Playgroud)

这是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!
Run Code Online (Sandbox Code Playgroud)

并输出:

测试......像包装一样嘎嘎叫......没有找到覆盖!嘎嘎叫像ClassA Base像包装一样嘎嘎叫......没有找到覆盖!像ClassA Base一样嘎嘎叫

因此,在python中派生的基类和类都是相同的.由于某种原因,它似乎没有找到覆盖.我不确定,但这可能与create()函数有关.任何想法将不胜感激!

编辑:

在py脚本中添加了pythonquack - 这可以按预期工作:

def pythonquack( Inst ):
    print Inst
    Inst.quack()
Run Code Online (Sandbox Code Playgroud)

正如我所料,将它称为Ainst和Dinst称为"Quacks like a Base"和"Quacks like a Derived".因此,由于某种原因,覆盖不会被传递回C++.

Jon*_*ott 1

我最终使用 intrusive_ptrs 重新思考了我的设计。使用包装器比使用shared_ptr 需要做更多的工作,但效果相当好。感谢大家抽出时间。