10

如何从 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
4

6 回答 6

9

当我最终遇到默认构造函数没有剪切它的情况时,我将实例变量设为指针,然后newinit方法和方法delete中使用dealloc

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

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

于 2012-09-17T21:29:50.287 回答
5

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

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

于 2012-09-17T21:38:59.773 回答
3

如果您已经在 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
于 2018-09-15T01:14:17.973 回答
1

只是为了好玩——我找到了一个使用模板的部分解决方案,但我怀疑你会得到很多“真实世界”的里程......

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

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

于 2012-09-17T22:32:52.757 回答
0

另一种解决方案是创建一个包装器CppClass,并在该包装器中提供构造函数参数,例如:

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
于 2021-05-08T03:48:21.803 回答
-1

我还没有尝试过,但为了好玩,我只想重复一下:

首先这看起来是错误的:

@interface ObjC: NSObject {
  CppClass _cppClass;
}
@end

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

尝试

CppClass *_cppClass;

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

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

_cppClass = new CppClass(pass constructor args here

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

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

因此,您需要为您的 C++ 类提供一个单独的标头和 impl,就像通常那样,您只需在您的 obj 类中包含 CPP 标头和代码 CPP。

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

于 2012-09-17T21:36:50.103 回答