C++引用類型實例變量作爲實例變量是禁止++在Objective-C。我該如何解決這個問題?C++引用類型如在Objective-C++
回答
不能合理使用作爲實例變量的引用,因爲沒有辦法來初始化實例變量和引用不能被重新插拔一下。
另一種可能是簡單地使用(可能是智能)指針來代替。
,讓你更接近C++的另一種可能性 - 樣的行爲是使用PIMPL風格的成員你的C++成員:
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
boost :: ref()可能有幫助嗎?
不是真的 - 'reference_wrapper
一個更通用的解決方案是使用reference_wrapper<T>
而不是自定義結構。最終結果是相似的。
話又說回來,如果你只需要存儲一個成員,你不能用無論是結構還是這個包裝要越過指針太大的優勢。 (感謝喬治!)
我用喬治的回答爲出發點的例子:
// 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-02 11:27:31
爲什麼不呢。想想看,在實際上和例子一樣簡單的情況下,我通常只是存儲一個指針。 – 2014-04-02 14:07:02
喬格的第一句話是完全正確的:
不能合理使用作爲實例變量的引用,因爲沒有辦法來初始化實例變量和引用不能被重新插拔一下。
但我不認爲他的解決方案是最好的之一。
一個指針和一個參考值之間的語義差小。引用本質上是一個不能爲空的指針。所以在你的界面中使用引用非常明顯,nullptr
不是一個有效的初始化參數。但在內部,你可以簡單地存儲指針:
@interface A : NSObject {
SomeClass* p;
}
- (id)initWithRef:(SomeClass&)ref;
@end
@implementation A
- (id)initWithRef:(SomeClass&)ref {
if(self = [super init]) {
p = &ref;
}
return self;
}
@end
沒有更多(在最壞的情況下:手動)內存分配,沒有資源處理在所有,任何額外的間接等A的每個成員都可以簡單地斷言p != nullptr
。
如果您可以修改需要您斷言/檢查一次的選項,那麼斷言A中的每個成員似乎都很麻煩並且容易出錯。 – 2015-08-24 12:25:39
這與斷言您的pimpl指針在每個成員中仍然有效沒有什麼不同。也許它太偏執了,但它適用於這兩種解決方案。 – Sebastian 2015-08-24 13:11:00
- 1. 從ObjectiveC類中引用UIViewController
- 2. C# - 引用類型引用另一個引用類型
- 3. c#值類型和引用類型
- 4. C#屬性引用類型?
- 5. 將C#引用類型克隆到派生引用類型
- 6. 在C#中,使用的值類型與引用類型
- 7. 在XML模式中引用C#類型?
- 8. 推薦類型讀的 - 的ObjectiveC
- 9. 編組引用類型從C++到C#
- 10. 從Objectivec中調用C main
- 11. 如何在C#中引用特定的類類型?
- 12. 綁定的ObjectiveC類的C#問題
- 13. 從類圖生成Objectivec C代碼
- 14. C#==在值類型和引用類型方面有所不同?
- 15. 在ObjectiveC代碼中使用C++類中的靜態字段
- 16. Mono.Cecil類型引用類型?
- 17. 對值類型和引用類型使用C#LINQ表達式
- 18. 引用類型
- 19. 引用類型
- 20. C#傳引用類型VS out參數
- 21. C++簡單引用類型函數
- 22. 類型或引用丟失。 C#
- 23. C#引用類型的行爲
- 24. C++刪除char類型的引用
- 25. C# - 值類型的引用包裝
- 26. C#交叉引用泛型類
- 27. 如何在基本類型引用中存儲對派生類型的引用?
- 28. C#引用類型賦值VS值類型賦值
- 29. C#泛型類型引起歧義
- 30. 右值引用的類型推演在C++ 11 C++ 11
是的,就是這樣! – 2010-04-30 17:39:09
我不明白爲什麼你不只是存儲一個指向SomeClass本身的指針。引用和指針之間的區別(大部分)是您的界面完美傳輸的語義之一。看到我的答案。 – Sebastian 2015-08-24 10:53:15
@Sebastian如果你只有一個成員初始化(你多久只有一個成員?),這是沒有意義的。如果您初始化多個成員並希望返回適當的確定性行爲,這會變得很有趣。 FWIW,我提到了指針和這種方法作爲可能的選擇。 – 2015-08-24 12:18:48