从Objective C类调用C ++构造函数

时间:2022-09-07 07:54:08

How can I call a C++ constructor from inside an Objective C class?

如何从Objective C类中调用C ++构造函数?

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

5 个解决方案

#1


7  

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.

当我最终在默认构造函数没有剪切它的情况下,我将实例变量作为指针,然后在init方法中使用new并在dealloc方法中删除。

It's a relatively recent thing that default constructors are called at all for Objective-C instance variables, actually.

实际上,对于Objective-C实例变量,默认构造函数被调用是一个相对较新的事情。

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.

没有Objective-C语言的规范,更不用说Objective-C ++扩展的规范了。 Apple确实发布了一个名为The Objective-C Programming Language的文档,但是它几乎没有提到C ++,所以当你需要澄清一些不明显的东西时,你经常会自己离开。但是,Clang邮件列表中的人员通常知道的更好。

#2


5  

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).

如果你需要一个基于堆栈的C ++类作为你的obj-c类的ivar,那么你就不能将任何参数传递给构造函数。该类将构建为obj-c对象分配的一部分。您可以在-init中使用赋值运算符,也可以以其他方式修改嵌入对象(例如,使用成员函数等)。

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).

如果该类绝对需要使用参数构造,那么您不能使用基于堆栈的对象,而必须使用new在堆上分配它(然后在-dealloc中使用delete删除它)。

#3


1  

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)

请注意,int模板参数可以是文字,但是const char []模板参数必须在具有外部链接的变量中声明..(根据clang)

#4


0  

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.

如果您已经在ObjC中使用C ++,那么也可以将其作为智能指针,这样您就不必担心添加清理位了。

#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

#5


-1  

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.

看看你在obj c类的接口中声明了一个基于堆栈的类。

Try

CppClass *_cppClass;

Then as long as you have included the CppClass in your file

然后,只要您在文件中包含CppClass

You should since obj C interops with both C and C++ be able to create an instance with

你应该因为obj C与C和C ++的interop能够创建一个实例

_cppClass = new CppClass(pass constructor args here

I wouldnt recommed putting the C++ class in the same file

我不建议将C ++类放在同一个文件中

In an obj C project you need a .mm file - not sure if declarations for CPP are included in that. Proly not.

在obj C项目中,您需要.mm文件 - 不确定CPP的声明是否包含在其中。没有。

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.

所以你需要一个单独的头和impl用于你的C ++类,因为你通常只需要在你的obj类中包含CPP头和代码CPP。

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.

我可以离开这里,没有尝试过但是,只要你遵守规则,obj C似乎优雅地能够调用C和C ++。

#1


7  

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.

当我最终在默认构造函数没有剪切它的情况下,我将实例变量作为指针,然后在init方法中使用new并在dealloc方法中删除。

It's a relatively recent thing that default constructors are called at all for Objective-C instance variables, actually.

实际上,对于Objective-C实例变量,默认构造函数被调用是一个相对较新的事情。

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.

没有Objective-C语言的规范,更不用说Objective-C ++扩展的规范了。 Apple确实发布了一个名为The Objective-C Programming Language的文档,但是它几乎没有提到C ++,所以当你需要澄清一些不明显的东西时,你经常会自己离开。但是,Clang邮件列表中的人员通常知道的更好。

#2


5  

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).

如果你需要一个基于堆栈的C ++类作为你的obj-c类的ivar,那么你就不能将任何参数传递给构造函数。该类将构建为obj-c对象分配的一部分。您可以在-init中使用赋值运算符,也可以以其他方式修改嵌入对象(例如,使用成员函数等)。

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).

如果该类绝对需要使用参数构造,那么您不能使用基于堆栈的对象,而必须使用new在堆上分配它(然后在-dealloc中使用delete删除它)。

#3


1  

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)

请注意,int模板参数可以是文字,但是const char []模板参数必须在具有外部链接的变量中声明..(根据clang)

#4


0  

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.

如果您已经在ObjC中使用C ++,那么也可以将其作为智能指针,这样您就不必担心添加清理位了。

#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

#5


-1  

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.

看看你在obj c类的接口中声明了一个基于堆栈的类。

Try

CppClass *_cppClass;

Then as long as you have included the CppClass in your file

然后,只要您在文件中包含CppClass

You should since obj C interops with both C and C++ be able to create an instance with

你应该因为obj C与C和C ++的interop能够创建一个实例

_cppClass = new CppClass(pass constructor args here

I wouldnt recommed putting the C++ class in the same file

我不建议将C ++类放在同一个文件中

In an obj C project you need a .mm file - not sure if declarations for CPP are included in that. Proly not.

在obj C项目中,您需要.mm文件 - 不确定CPP的声明是否包含在其中。没有。

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.

所以你需要一个单独的头和impl用于你的C ++类,因为你通常只需要在你的obj类中包含CPP头和代码CPP。

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.

我可以离开这里,没有尝试过但是,只要你遵守规则,obj C似乎优雅地能够调用C和C ++。