Reputation: 2540
I have a c++ class implemented in a objective-c++ (.mm) file.
This class contains some Cocoa object, say a NSToolbar
, as a (private) member variable.
The class should be exposed as a pure c++ interface and usable by pure c++ clients.
In other words, I am trying to wrap obj-c objects in a c++ class.
The first thing that crosses my mind is to use a void pointer in the class interface
and then work around with casting within the class implementation, whenever _toolbar
needs to be treated as a NSToolbar
.
For example I would have the interface:
// NSToolbarWrapper.h
class NSToolbarWrapper {
private:
void * _toolbar;
//... rest of the class ...
}
and the implementation:
// NSToolbarWrapper.mm
...
ToolbarWrapper::ToolbarWrapper (...){
_toolbar = (__bridge void *)[[NSToolbar alloc] initWithIdentifier:@"My toolbar!"];
...
}
I am not sure this is the smartest approach. Is there a best practice in this case?
Upvotes: 2
Views: 1383
Reputation: 2540
For the sake of documentation, and to remind myself in the future.
I have seen a pretty well-known open source library doing like this, which also seems to be a valid approach:
// NSToolbarWrapper.h
#ifdef __OBJC__
typedef NSToolbar *Toolbar;
#else
typedef class NSToolbar_opaque *Toolbar;
#endif // __OBJC__
class NSToolbarWrapper {
private:
Toolbar _toolbar;
//... rest of the class ...
}
Upvotes: 0
Reputation: 69864
Pimpl idiom with c++ interface and objective c++ implementation. You'll need to declare your destructor and define it in the .mm file if you use unique_ptr as your pimpl;
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
};
class.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
Upvotes: 4