What does the const specifier do, before a pointer to object?

家住魔仙堡 提交于 2019-12-31 03:21:26

问题


If I have a C-string like this:

const char* str= "hello";

I know well that I can't change any character of the string because the pointer is const.
But if I have this:

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

I can still mutate the object state using it's methods.
If the pointer is to a NSMutableString, I'm still able to mutate it.
Then what does the const stand for?


回答1:


In that method declaration, location is a pointer to a constant CLLocation. But when you send a message to the location object, the const-ness is not preserved; the method that handles the message sees self as a non-const object. (Note that this is different than C++, which supports const member functions where this is a pointer to a constant object.)

So the const in that declaration is not particularly useful. Perhaps it was written by someone used to the C++ way of doing things.

When you do see const attached to an object pointer in Objective-C, it is usually like this:

extern NSString * const SomeConstantString;

This declares SomeConstantString as a constant pointer to some non-constant object (in this case, an NSString). The pointer itself is constant, so your program can't change SomeConstantString to point to some other NSString object.




回答2:


I know well that I can't change any character of the string because the pointer is const.

No, the pointer is mutable. The characters it points to are const.

I can still mutate the object state using it's methods.

There is no const-correctness for Objective-C objects like there is in C++. The compiler does not care which messages (mutating or not) you send to a const object. So there's no sense in declaring a pointer to a const object. The cited framework method is an anomaly, probably an oversight.




回答3:


Mind the difference:

// constant pointer
char * const str = "";

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

The keyword const applies applies to whatever is immediately to its left. If there is nothing to its left, it applies to whatever is immediately to its right.

In Objective-C all method parameters are always passed by value. This includes primitives, structs, unions, and pointers, and any other made up type.

Note that you can't have variables of type object. A expression like NSObject o; produces a compiler error with message "Interface type cannot be statically allocated".

The only way to pass an object is passing a pointer. The pointer is passed as value, but lets the code inside the method reference the object and change it. So in a way, it is as if you are passing the object by reference (in reality you are passing the pointer by value).

When compiling an Objective-C program, the methods are turned into C functions, and each "message send" (aka "method call", though it isn't exactly the same) is ran using the runtime function objc_sendMsg. This function doesn't know or care if you qualified the object with const or not. If you want an immutable object, you have to code that immutability inside the object. Example:

// 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];


来源:https://stackoverflow.com/questions/13652508/what-does-the-const-specifier-do-before-a-pointer-to-object

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!