我经常给我的类一个私有的typedef引用自己,如下所示:
class MyClass {
private:
typedef MyClass Self;
public:
void DeepCopyFrom(const Self& other);
...
};
我现在正在使用SWIG包装我的C ++代码,SWIG抱怨这样的typedef:
error: ‘typedef class MyClass MyClass::Self’ is private
导致此错误的包装器代码如下所示:
SWIGINTERN PyObject *_wrap_MyClass_DeepCopyFrom(PyObject *SWIGUNUSEDPARM(self), PyObject *args) {
PyObject *resultobj = 0;
MyClass *arg1 = (MyClass *) 0 ;
MyClass::Self *arg2 = 0 ;
(...)
编译器错误发生在省略号上方的最后一行。
有没有办法告诉SWIG不使用私有typedef,而只是使用完整的类型名称?
答案 0 :(得分:2)
我建议保持简单(r):只需删除typedef并改写类名。
如果你真的讨厌这个,你可以告诉SWIG %ignore
“破碎”的方法,然后%extend
使用包装器方法调用真实的方法。除非你绑定的类和方法的数量相对于你的总代码库很小,否则这种治疗可能比疾病更糟。
答案 1 :(得分:1)
默认情况下,SWIG不会处理private
部分中的任何typedef或声明或任何内容。因此,它假定(当它看到const Self&
)Self
是标题或其他内容中的某种未知类型时,它会保留原样,并生成包含Self
的包装代码。问题是这个包装器代码是类外部的函数,并且由于MyClass::Self
是私有的,因此编译器会生成错误。我的代码也发生了同样的事情:我要做的就是在public
部分声明typedef或者将Self
重写为MyClass
。将typedef更改为public
对我来说最有意义。
答案 2 :(得分:0)
我很少见过私有typedef,但我认为封装的概念没有任何问题。但是,如果你有一个使用typedef的公共函数,那么不会使你的接口成为typedef的一部分吗?
我想你可以在一些成员函数或私有成员函数接口中使用私有typedef。但是如果你想在公共方法上使用它,那么只有typedef才公开才有意义。
我不知道关于这个主题的标准是什么,但我猜它是为数不多的灰色区域之一。我假设它依赖于编译器关于如何处理类中的typedef的实现,您可以确定在公共方法中使用私有typedef是否可以接受(甚至可以接受)。为了安全起见,我会公之于众。
如果您担心暴露typedef,那么不要在任何公共成员函数的原型中使用它(并且仍然可能被某些编译器拒绝)。如果您担心名称冲突,请不要这样做,因为任何外部代码都必须使用实际的类名来解析范围。
我认为你可能只是把封装想法放得太过分了。
答案 3 :(得分:0)
当您需要opaque类型时,请改用不完整的类(并在实现文件中完成它,而不是头文件)。
但是在你的特定例子中,我不认为应该使用opaque类型。