6.27 内部类

如果目标语言支持内嵌类的概念(如Java),则内嵌的C++类被包装成目标语言内嵌的代理类。(在Java中表示为static内嵌类。)只有公有的内嵌类才能被包装。否则内嵌C++类和一般类没什么区别。

如果目标语言不直接支持内嵌类,或者目标语言模块不支持(比如现在的Python),则内嵌类被移至包含类一样的名称空间中(内嵌结构被展平)。类似的行为可以通过%feature("flatnested")特征指令在C#和Java中开启;如果外层名称空间中有一样名字的类,可以通过重命名或忽略解决:

  1. %rename (Bar_Foo) Bar::Foo;
  2. class Foo {};
  3. class Bar {
  4. public:
  5. class Foo {};
  6. };

如果一个内嵌类使用了外层类的模板参数,则模板就得在外层类的前面使用%template指令提前实例化。在模板这一节会找到这样的例子。

兼容性注释:在SWIG-3.0.0之前,对内嵌类的支持有限。内嵌类被当做透明指针。但是,老版本中对内嵌类的支持需要用户复制内嵌类到全局命名空间中,添加内嵌类的typedef,并在内嵌类上使用nestedworkaround特征。这与flatnested特征做同样的事情。SWIG-3.0.0开始对内嵌类的正确支持可以使用了,以前的特征作废,使用它们的代码需要修改。如果你看到这样的警告:

​ example.i:8: Warning 126: The nestedworkaround feature is deprecated

考虑使用上面讨论的flatnested特征生成非内嵌的代理类。或则,使用默认的内部类代码生成机制在目标代码中生成内部代理类的等效版本,这依赖目标语言的支持。

SWIG-1.3.40和早期的版本没有nestedworkaround特征,对内部类生成的代码总是不能正确编译。及时使用%warnfilter也不能抑制这类关于内部类的警告。