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