是的,如果您知道一些技巧,这两种方式都很容易实现:
1)“id”类型实际上是在纯 C 标头中定义的。因此,您可以执行以下操作:
在您的标题中:
#include <objc/objc.h>
class MyWindow
{
public:
MyWindow();
~MyWindow();
protected:
id mCocoaWindow;
};
在您的实施中(.mm):
#include "MyWindow.h"
#include <Cocoa/Cocoa.h>
MyWindow::MyWindow()
{
mCocoaWindow = [[NSWindow alloc] init];
}
MyWindow::~MyWindow()
{
[mCocoaWindow release];
mCocoaWindow = nil;
}
2) 当源文件包含两者之一但不是 ObjC++ 时,可以使用两个预处理器常量来排除 C++/ObjC 特定代码:
#if __OBJC__
// ObjC code goes here.
#endif /* __OBJC__*/
#if __cplusplus
// C++ code goes here.
#endif
请注意,您不能只使用#ifdef 添加/删除 ivars 或虚拟方法,这将创建两个具有不同内存布局的类,并使您的应用程序以非常奇怪的方式崩溃。
3)您可以使用指向结构的指针而不声明其内容:
在您的标题中:
@interface MyCppObjectWrapper : NSObject
{
struct MyCppObjectWrapperIVars *ivars; // This is straight ObjC, no ++.
}
@end
在您的实现文件 (.mm) 中:
struct MyCppObjectWrapperIVars
{
std::string myCppString1;
std::string myCppString2;
std::string myCppString3;
};
@implementation MyCppObjectWrapper
-(id) init
{
if(( self = [super init] ))
{
ivars = new MyCppObjectWrapperIVars;
}
return self;
}
-(void) dealloc
{
delete ivars;
ivars = NULL;
[super dealloc];
}
@end
这将使您的标头简单的标准 C 或 ObjC,而您的实现文件获取所有 ivars 的构造函数/析构函数调用,而无需创建/删除每个作为堆上的对象。
这只是 Mac 方面的事情,但这意味着您可以将 ObjC 内容保留在您的标头之外,或者至少在从 C++ 可移植性层的 Mac 实现的跨平台客户端文件中使用它时使其编译。