【问题标题】: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];