SWIG:在派生类中处理基类重载方法

时间:2012-11-22 04:35:14

标签: c++ python inheritance swig overloading

我很难在SWIG中做出这样的优雅......

我有一个基类,它包含一个重载方法create:

class Base {
public:
    virtual Foo *create(ClassA &, ClassB &) = 0;
    Foo *create(int id) {
        // get ClassA a and ClassB b from an internal store related to id
        return create(a, b);
    }
};

这当然是SWIG包装没有麻烦。

在其他位置/存储库中,有几个不同的Base派生类,它们当然定义了自己的纯虚拟创建版本(ClassA&,ClassB&)方法 - 但它们不需要定义创建( int)variant,因为基类版本应该足够了。

这些派生类的SWIG包装只能看到派生类中定义的create()方法,并且不提供带有单个int参数的变量,即使它们应该从基类继承它。

我尝试使用%rename作为基类的方法来获取有用的东西,例如。

%rename (_create1) Base::create(ClassA&,ClassB&);
%rename (_create2) Base::create(int);

%extend (Base) {
    %pythoncode {
        def create(self, a_or_id, b=None):
            if b is not None:
                self._create1(a_or_id, b):
            else:
                self._create2(a_or_id)
    }
}

这在生成的python / _wrap.cc代码中似乎很好,但是派生类的包装器将只包装create()方法,就好像%renames不存在一样。

他们在单独的.i文件中,但派生类的.i文件各自导入基类.i文件,因此python类继承是正确的,它只是C ++类的继承,有点被这种压倒性的方法击败了。

理想情况下,我想要一个解决方案,我不必在所有派生类的.i文件中插入%rename语句(虽然我知道这可以解决问题),但这只是意味着大量的重复码。

有什么想法吗?

1 个答案:

答案 0 :(得分:3)

你确定这些类声明正确吗?派生类中具有相同名称的虚方法隐藏基类方法,除非using将基本函数带入派生命名空间。例如:

class A
{
    public:
        void func(int a);
        virtual void func(int a,int b);
};

class  B : public A
{
    public:
        //using A::func;
        virtual void func(int a,int b);
};

使用SWIG和Python我无法写:

b = B()
b.func(1)    # failed
b.func(1,2)

没有取消注释上面的using行,并且这些类在C ++中也无法正常工作。使用using,SWIG正确地将函数暴露给Python,C ++也起作用。