簡體   English   中英

Objective-C ++和運算符->

[英]Objective-C++ and operator ->

我對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的實例變量和一個名為namesetName:的setter和getter。 在Objective-C中,此語法為:

value = object.name;

等效於以下語法:

value = [object name];

即編譯為調用getter的方法分派。 同樣,這:

object.name = value;

等效於:

[object setName:value];

即,將其編譯為調用setter的方法分派。 無論哪種情況,您都不會訪問實例變量。 在這兩種情況下,您都在調用setter和getter。 如果希望,可以實現User不具有實例變量支持name ,將其完全放在其他位置,或將其與其他形式進行相互轉換。

線索是以下是有效的Objective C語法:

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

在C和C ++中,點運算符不適用於指針。

在Objective-C中公開直接成員變量訪問是不正常的。 為了進行適當的包裝,您需要為每個屬性編寫實際的getter和setter方法。 hack方法將類似於:

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

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

[...]

@implementation User
@synthesize name;
@end

這將:

  • 創建一個實例變量, name
  • 為屬性(也稱為name創建一個setter和一個getter。
  • 確保setter和getter使用實例變量作為屬性;
  • 還公開了實例變量以通過->直接訪問。

無論是從設計還是從可維護性的角度,以及允許您使用其他Objective-C功能(例如鍵值觀察),直接實例變量操作實際上都是一個非常糟糕的主意。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM