インスタンス変数としての C++ 参照型は、Objective-C++ では禁止されています。どうすればこれを回避できますか?
2722 次
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 に答える