4

インスタンス変数としての C++ 参照型は、Objective-C++ では禁止されています。どうすればこれを回避できますか?

4

4 に答える 4

9

インスタンス変数を初期化する方法がなく、参照を再設定できないため、参照をインスタンス変数として賢明に使用することはできません。

代わりに、代わりに (おそらくスマートな) ポインターを使用することもできます。

C++ のような動作に近づけるもう 1 つの可能性は、C++ メンバーに PIMPL スタイルのメンバーを使用することです。

struct CppImpl {
    SomeClass& ref;
    CppImpl(SomeClass& ref) : ref(ref) {}
};

@interface A : NSObject {
    CppImpl* pimpl;    
}
- (id)initWithRef:(SomeClass&)ref;
@end

@implementation    
- (id)initWithRef:(SomeClass&)ref {
    if(self = [super init]) {
        pimpl = new CppImpl(ref);
    }
    return self;
}
// clean up CppImpl in dealloc etc. ...
@end
于 2010-04-30T16:55:31.063 に答える
0

より一般的な解決策はreference_wrapper<T>、カスタム構造体の代わりに使用することです。最終結果は似ています。

繰り返しますが、1 つのメンバーのみを格納する必要がある場合は、構造体またはこのラッパーのいずれかを使用しても、ポインターよりも多くの利点を得ることはできません。(ありがとうジョージ!)

例の出発点として、ゲオルクの答えを使用しました。

// This bare interface can be used from regular Objective-C code,
// useful to pass around as an opaque handle
@interface A : NSObject
@end

// This interface can be shown to appropriate Objective-C++ code
@interface A (Private) // @interface A () if it's just for this class's .mm file
- (id)initWithRef:(SomeClass &)ref;
@property (readonly, nonatomic) SomeClass &ref;
@end


@implementation A {
    reference_wrapper<SomeClass> *_refWrapper;    
}

- (id)init {
    // and/or throw an exception
    return nil;
}

- (id)initWithRef:(SomeClass &)ref {
    self = [super init];
    if(self) {
        _refWrapper = new reference_wrapper<SomeClass>(ref);
    }
    return self;
}

- (SomeClass &)ref {
    // reference_wrapper<T> is implicitly convertible to T&
    return *_refWrapper;
    // This would also work:
    // return _refWrapper->get();
}

- (void)dealloc {
    delete _refWrapper;
}

@end

この複数のヘッダー パターンは、Objective-C コードで不透明なハンドルを渡すのに役立ちますが、Objective-C++ の機能を選択した少数 (たとえそれがその objc クラスの実装であっても) に提供します。

于 2014-04-01T18:20:47.613 に答える
0

boost::ref() が役立つ場合がありますか?

于 2010-04-30T16:52:34.547 に答える