【问题标题】:Wrapping objective-c classes into c++ classes: best practices?将objective-c 类包装成c++ 类:最佳实践?
【发布时间】:2014-10-01 13:27:33
【问题描述】:

我在objective-c++ (.mm) 文件中实现了一个c++ 类。 此类包含一些 Cocoa 对象,例如 NSToolbar,作为(私有)成员变量。 该类应作为纯 c++ 接口公开,并可供纯 c++ 客户端使用。 换句话说,我试图将 obj-c 对象包装在 c++ 类中。

我首先想到的是在类接口中使用 void 指针 然后在需要将_toolbar 视为NSToolbar 时,在类实现中解决强制转换问题。

例如我会有界面:

// NSToolbarWrapper.h
class NSToolbarWrapper {
private:
void * _toolbar;

//... rest of the class ...

}

和实施:

// NSToolbarWrapper.mm
...
ToolbarWrapper::ToolbarWrapper (...){
_toolbar = (__bridge void *)[[NSToolbar alloc] initWithIdentifier:@"My toolbar!"];
...
}

我不确定这是最聪明的方法。 在这种情况下是否有最佳做法?

【问题讨论】:

  • 我发现最好的方法是在声明将暴露给纯 c++ 的类时使用 pimpl 习惯用法

标签: c++ objective-c wrapper


【解决方案1】:

具有 c++ 接口和目标 c++ 实现的 Pimpl 成语。 如果你使用 unique_ptr 作为你的 pimpl,你需要声明你的析构函数并在 .mm 文件中定义它;

class.h:

class myclass {
    class impl;
    std::unique_ptr<impl> _impl; // or shared_ptr if you want shared handle behaviour

public:
    myclass(const char* s);
    ~myclass(); // only declare here
};

类.mm:

class myclass::impl {
    NSString* _str;
public:
    impl(const char* s) 
    : _str([NSString stringWithCString:s encoding: NSASCIIStringEncoding]) 
    {}
};

myclass::myclass(const char* s)
: _impl(new impl(s))
{}

myclass::~myclass() = default;  // define here

【讨论】:

    【解决方案2】:

    为了记录,也为了以后提醒自己。

    我见过一个非常知名的开源库这样做,这似乎也是一种有效的方法:

    // NSToolbarWrapper.h
    #ifdef __OBJC__
    typedef NSToolbar *Toolbar;
    #else
    typedef class NSToolbar_opaque *Toolbar;
    #endif // __OBJC__
    
    class NSToolbarWrapper {
    private:
    Toolbar _toolbar;
    
    //... rest of the class ...
    
    }
    

    【讨论】:

      猜你喜欢
      • 2013-11-08
      • 1970-01-01
      • 2010-11-11
      • 2010-10-08
      • 2010-09-12
      • 2011-01-27
      • 1970-01-01
      • 1970-01-01
      • 2012-03-18
      相关资源
      最近更新 更多