views:

588

answers:

6

What is the difference between

void func(const Class *myClass)

and

void func(Class *const myClass)


See also:

and probably others...

+16  A: 

The difference is that for

void func(const Class *myClass)

You point to a class that you cannot change because it is const. But you can modify the myClass pointer (let it point to another class; this don't have any side effects to the caller because it's pointer is copied, it only changes your local the pointer copy) In contrast

void func(Class *const myClass)

Now myClass points to a class that can be modified while you cannot change the parameter.

rstevens
+8  A: 

In the first one you're declaring a function that accepts a pointer to a constant Class object. You cannot modify the object inside the function. In the second one you're declaring a function that accepts a constant pointer to a non constant Class object. You can modify the object through the pointer, but cannot modify the pointer value itself.

I always keep in mind this easy rule: const always applies on the thing at the immediate left of it, if this thing doesn't exists, it applies to the thing on the immediate right.

Also take a look to this question which I asked a week ago, it points to some very useful links to understand const correctness.

tunnuz
+1 for a good answer and the tip on how to remember const-ness, that's the one I use too.
xan
+1  A: 

In C++ this

const MyClass *ptr

and this

MyClass const *ptr

both mean that ptr is a variable pointer that points to a constant object of type MyClass. That is, you can't change the said object through ptr. However, you can make ptr itself point some other object of MyClass.

In contrast, this

MyClass *const ptr

implies ptr is a constant pointer pointing to a variable MyClass object. Here you can indeed change the object that ptr is pointing to, but you cannot make ptr to point to some other object.

Note that among the above three kinds of syntax, the second one is a bit odd, but it is valid syntax. It doesn't follow the left to right reading rule that other folks here have suggest. But then, that's life in C++ for you.

Frederick
+2  A: 

A rule of thumb is to read the declarations right to left:

void func(const Class *myClass) is a pointer to a const Class (or strictly speaking "a pointer to a Class which is const")

void func(Class *const myClass) is a const pointer to a Class

jalf
for very loose definitions of right->left. Strictly, the first seems more like 'pointer to a Class const' to me
drhorrible
This rule breaks down upon seeing this: MyClass const *ptr
Frederick
drhorrible: "a class which is const" then, if you want to be pedantic. ;)Frederick: Why? A pointer to a const MyClass? Seems straightforward.
jalf
+1  A: 

The trick is to read theese things backwards:

void func(const Class *myClass)

Reads "myClass is a pointer to a Class that is const" wich means I can't make changes in Class

void func(Class *const myClass)

Reads "myClass is a const pointer to a Class" wich means I can't change the pointer.

c0m4
+1  A: 
void func(const Class *myClass) { //...

As mentioned in other answers, this definition means that the parameter myClass points to an instance of Class that may not be modified (mutable and const_cast excepted) by the function. However the myClass variable in the function body could be change to point at a different instance of Class. This is an implementation detail of the function.

void func(Class *const myClass) { // ...

On the other hand this definition means that the myClass parameter is a pointer to a Class instance that is not const and hence can be used by the function to fully manipulate the class instance, but that the myClass pointer variable itself cannot be altered to point at anything else in the function body.

One important point that hasn't been raised by other answers is that for function signatures, any top level const or volatile qualification is disregarded when considering the type of the function. This is because parameters are always passed by value, so whether they are const or not only affects whether the parameter itself can be changed in the body of the function and cannot affect the caller.

Thus these two function declarations are equivalent.

void func(Class *const myClass);

void func(Class *myClass);
Charles Bailey