【问题标题】:What does the const specifier do, before a pointer to object?const 说明符在指向对象的指针之前做什么?
【发布时间】:2012-11-30 20:16:00
【问题描述】:

如果我有这样的 C 字符串:

const char* str= "hello";

我很清楚我不能更改字符串的任何字符,因为指针是 const。
但如果我有这个:

- (CLLocationDistance)distanceFromLocation:(const CLLocation *)location

我仍然可以使用它的方法改变对象状态。
如果指针指向 NSMutableString,我仍然可以对其进行变异。
那么 const 代表什么?

【问题讨论】:

    标签: objective-c constants cllocation


    【解决方案1】:

    在该方法声明中,location 是指向常量 CLLocation 的指针。但是当您向location 对象发送消息时,const-ness 不会被保留;处理消息的方法将self 视为非const 对象。 (请注意,这与 C++ 不同,后者支持 const 成员函数,其中 this 是指向常量对象的指针。)

    因此,该声明中的const 并不是特别有用。也许它是由习惯于 C++ 做事方式的人编写的。

    当你在 Objective-C 中看到 const 附加到对象指针时,通常是这样的:

    extern NSString * const SomeConstantString;
    

    这将SomeConstantString 声明为指向某个非常量对象的常量指针(在本例中为NSString)。指针本身是常量,因此您的程序无法更改 SomeConstantString 以指向其他 NSString 对象。

    【讨论】:

      【解决方案2】:

      我很清楚我不能更改字符串的任何字符,因为 指针是常量。

      不,指针是可变的。它指向的字符是const。

      我仍然可以使用它的方法改变对象状态。

      Objective-C 对象没有像 C++ 中那样的 const 正确性。编译器不关心您发送到 const 对象的消息(变异与否)。所以声明一个指向 const 对象的指针是没有意义的。引用的框架方法是异常的,可能是疏忽。

      【讨论】:

        【解决方案3】:

        注意区别:

        // constant pointer
        char * const str = "";
        
        // pointer to constant (two equivalent ways)
        const char * str = "";
        char const * str = "";
        

        关键字 const 适用于紧邻其左侧的任何内容。如果左侧没有任何内容,则适用于其右侧的任何内容。

        在 Objective-C 中,所有方法参数总是按值传递。这包括原语、结构、联合和指针,以及任何其他组成的类型。

        请注意,您不能有对象类型的变量。 NSObject o; 之类的表达式会产生编译器错误,并显示消息“无法静态分配接口类型”。

        传递对象的唯一方法是传递指针。指针作为值传递,但让方法内的代码引用对象并更改它。所以在某种程度上,好像你通过引用传递对象(实际上你是通过值传递指针)。

        在编译 Objective-C 程序时,方法被转换为 C 函数,每个“消息发送”(也称为“方法调用”,虽然不完全相同)都使用运行时函数 objc_sendMsg 运行.这个函数不知道也不关心你是否用const 限定了对象。如果您想要一个不可变对象,则必须在对象内部编写该不可变性代码。示例:

        // const qualifying an object is ignored whether in variables or method arguments:
        const NSMutableArray *array = [NSMutableArray new];   // const is ignored
        -(void)someMethod:(const NSMutableArray *)array { ... // const is ignored
        
        // calling the methods that mutate the object works fine
        [array removeAllObjects];
        

        【讨论】:

          猜你喜欢
          • 2010-09-18
          • 1970-01-01
          • 1970-01-01
          • 2021-12-09
          • 2011-12-19
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多