Reputation: 7748
How can I call a C++ constructor from inside an Objective-C class?
class CppClass {
public:
CppClass(int arg1, const std::string& arg2): _arg1(arg1), _arg2(arg2) { }
// ...
private:
int _arg1; std::string _arg2;
};
@interface ObjC: NSObject {
CppClass _cppClass;
}
@end
@implementation ObjC
- (id)init
{
self = [super init];
if ( self )
{
// what is the syntax to call CppClass::CppClass(5, "hello") on _cppClass?
}
return self;
}
@end
Upvotes: 10
Views: 4440
Reputation: 1137
Another solution is create a wrapper for CppClass
, and provide constructor arguments in that wrapper, like:
class CppClass {
public:
CppClass(int arg1, const std::string& arg2): _arg1(arg1), _arg2(arg2) { }
// ...
private:
int _arg1; std::string _arg2;
};
namespace {
struct CppClassWrapper {
CppClass innerClass { 5, "hello" };
};
}
@interface ObjC: NSObject {
CppClassWrapper _cppWrapper;
}
@end
@implementation ObjC
- (id)init
{
self = [super init];
if ( self )
{
// use _cppWrapper.innerClass
}
return self;
}
@end
Upvotes: 0
Reputation: 2619
If you're already using C++ in your ObjC, might as well make it a smart pointer, so you don't have to worry about adding the cleanup bits.
#include <memory>
@interface ObjC: NSObject {
std::unique_ptr<CppClass> _cppClass;
}
@end
@implementation ObjC
- (id)init
{
self = [super init];
if ( self )
{
_cppClass.reset(new CppClass(5, "hello"));
}
return self;
}
@end
Upvotes: 3
Reputation: 16022
Just for kicks--I found a partial solution using templates, but I doubt you'll get much "real-world" mileage with it...
template <int X, const char Y[]>
class CPPClass
{
int _x;
const char * _string ;
public:
CPPClass();
};
template <int X, const char Y[]>
CPPClass<X, Y>::CPPClass()
: _x(X)
, _string(Y)
{
}
extern const char kHelloWorld[] = "hello world";
@interface MyObject : NSObject
{
CPPClass<5, kHelloWorld> thing;
}
@end
Note that the int
template parameter can be a literal in place, but the const char[]
template parameter must be declared in a variable with external linkeage.. (according to clang)
Upvotes: 1
Reputation: 138031
When I end up in a situation where the default constructor doesn't cut it, I make the instance variable a pointer and then use new
in the init
method and delete
in the dealloc
method.
It's a relatively recent thing that default constructors are called at all for Objective-C instance variables, actually.
There is no specification of the Objective-C language, let alone a specification of the Objective-C++ extension. Apple does publish a document called The Objective-C Programming Language, but it barely mentions C++, so you're often left on your own when you need to clarify something unobvious. The guys at the Clang mailing list often know better, though.
Upvotes: 9
Reputation: 185653
If you need a stack-based C++ class as an ivar of your obj-c class, then you cannot pass any arguments to the constructor. The class will be constructed as part of your obj-c object's allocation. You could use the assignment operator in your -init
, or you could modify your embedded object in some other way (e.g. using member functions, etc).
If the class absolutely needs to be constructed with arguments, then you cannot use a stack-based object and must instead allocate it on the heap with new
(and then delete it with delete
in your -dealloc
).
Upvotes: 5
Reputation: 3805
I havent tried this but for fun Im going to just riff on this:
First this looks wrong:
@interface ObjC: NSObject {
CppClass _cppClass;
}
@end
Look you are declaring a stack based class in the interface of an obj c class.
Try
CppClass *_cppClass;
Then as long as you have included the CppClass in your file
You should since obj C interops with both C and C++ be able to create an instance with
_cppClass = new CppClass(pass constructor args here
I wouldnt recommed putting the C++ class in the same file
In an obj C project you need a .mm file - not sure if declarations for CPP are included in that. Proly not.
So you need a separate header and impl for your C++ class as you normally would then just include the CPP header and code CPP in your obj class as normal.
I could be way off here, havent tried it but, obj C seems to gracefully be able to call C and C++ as long as you stick to the rules.
Upvotes: -1