c++ - Objective-C++ 和运算符 ->

标签 c++ objective-c clang objective-c++ clang++

我对 operator -> 和 Objective-C 有疑问。

我想在 ObjC 类上使用 C++ 包装器。

所以我创建了我的类:

@interface User : NSObject

@property (nonatomic, copy) NSString *name;

@end

还有包装类:

class UserWrapper {
    User *_user;
    //  ctors, accessors, etc.

    operator User *(){
        return _user;
    }

    User *operator->(){
        return _user;
    }
};

当我尝试通过 operator User* 访问支持对象时,效果很好:

UserWrapper wrapper([User new]);
[wrapper setName:@"alex"];
NSLog(@"%@", [wrapper name]);

但是当我尝试通过operator -> 访问这个对象时

UserWrapper wrapper([User new]);
[wrapper setName:@"alex"];
NSLog(@"%@", wrapper->name);

我有以下错误:

Property 'name' found on object of type 'User *'; did you mean to access it with the "." operator?

看来我对operator ->的理解是错误的。

有人可以解释我做错了什么,以及如何解决这个问题吗?

也许还有另一种方法可以直接访问支持对象?

最佳答案

在C、C++和Objective-C中,a->b表示解引用a并访问成员b。在 C 和 C++ 中,它与 (*a).b 相同但更直接。

如果 User 有一个名为 name 的成员,那么您对 ​​-> 的实现将是正确的,但事实并非如此。如果您根本没有编写其他代码,那么您的 User 有一个名为 _name 的实例变量以及一个名为 name设置名称:。在 Objective-C 中,这种语法:

value = object.name;

等价于此语法:

value = [object name];

即它被编译为调用 getter 的方法分派(dispatch)。同样,这:

object.name = value;

相当于:

[object setName:value];

即它被编译为调用 setter 的方法分派(dispatch)。在这两种情况下,您都不会访问实例变量。在这两种情况下,您都在调用 setter 和 getter。如果您愿意,您可以实现 User 而不是让实例变量支持 name,将其完全放在其他地方,或者将其与其他形式相互转换。

线索是以下是有效的 Objective C 语法:

User *object = [[User alloc] init];
object.name;

在 C 和 C++ 中,点运算符不适用于指针。

在 Objective-C 中暴露直接成员变量访问是不正常的。为了进行适当的包装,您需要为每个属性编写实际的 getter 和 setter。破解方法类似于:

@interface User: NSObject
{
    @public
       NSString *name;
}

@property (nonatomic, copy) NSString *name;
@end

[...]

@implementation User
@synthesize name;
@end

这会:

  • 创建一个实例变量,name
  • 为属性创建 setter 和 getter,也称为 name
  • 确保 setter 和 getter 使用属性的实例变量;
  • 还公开实例变量以通过 -> 直接访问。

直接实例变量操作确实是一个非常糟糕的主意,无论是从设计和可维护性的角度来看,还是从允许您使用其他 Objective-C 功能(如键值观察)的角度来看。

关于c++ - Objective-C++ 和运算符 ->,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16931667/

相关文章:

c++ - 查找最大值和最小值

c++ - 如果我想使用非标准的函数并且是由于编译器特定的 API,我该怎么办?

ios - 在Objective-C中创建后台循环例程的更好方法是什么?

c++ - 不明确的重载 - 带有参数包的部分函数模板排序

c++ - 在编译时使用注释自动包装 C/C++ 函数

constants - 如何在 LLVM IR 中初始化常量向量?

c++ - 错误LNK2019。 Unresolved external 。请教我我搞砸了什么。

c++ - 查找参数包的唯一值的数量

ios - 自适应弹出窗口上的关闭按钮

objective-c - 存储 JSON iTunes 搜索 API 数据