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

デフォルトのコンストラクターがそれをカットしない状況に陥った場合、インスタンス変数をポインターにしnewて、initメソッドとメソッドで使用します。deletedealloc

実際、Objective-C インスタンス変数に対してデフォルトのコンストラクターがまったく呼び出されるのは、比較的最近のことです。

Objective-C++ 拡張の仕様は言うまでもなく、Objective-C 言語の仕様はありません。Apple はThe Objective-C Programming Languageというドキュメントを公開していますが、C++ についてはほとんど触れていません。ただし、Clang メーリング リストの担当者はよく知っています。

于 2012-09-17T21:29:50.287 に答える
5

obj-c クラスの ivar としてスタックベースの C++ クラスが必要な場合、コンストラクターに引数を渡すことはできません。クラスは、obj-c オブジェクトの割り当ての一部として構築されます。で代入演算子を使用する-initか、埋め込みオブジェクトを他の方法 (メンバー関数の使用など) で変更することができます。

引数を使用してクラスを構築する必要がある場合は、スタックベースのオブジェクトを使用できず、代わりに でヒープに割り当てる必要がありますnew(その後、 で削除deleteします-dealloc)。

于 2012-09-17T21:38:59.773 に答える
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 の宣言が含まれているかどうかはわかりません。そうではありません。

したがって、通常はCPPヘッダーをインクルードし、通常どおりobjクラスにCPPをコード化するため、C++クラスには別のヘッダーとimplが必要です。

私はここから離れている可能性がありますが、試したことはありませんが、obj C は、規則に固執する限り、C および C++ を適切に呼び出すことができるようです。

于 2012-09-17T21:36:50.103 に答える