Need help with const pointers

Lately I've been teaching myself C++ through books and the net and it's been going very smoothly. I'm up to Ch.9 on this site which deals with references & pointers. Currently, I'm at "Passing a Const Pointer" but I can't quite understand what they're saying completely and I'd hate to move on without knowing the material, so I'm asking for a little help.

Just under the "Passing a Const Pointer", they mention the following (refers to figure 9.10):

Although passing a pointer to FunctionTwo() is more efficient, it is dangerous. FunctionTwo() is not allowed to change the SimpleCat object it is passed, yet it is given the address of the SimpleCat. This seriously exposes the object to change and defeats the protection offered in passing by value.

I'm wondering why this is considered dangerous, and why exactly is FunctionTwo() not allowed to change the object it is passed. I'm a bit confused by this since in the instructions leading up to this, we were passing variables by reference into similar functions, adjusting their values, and displaying the results in main. How is this different?

I'm also a tad confused by the prototype we use for FunctionTwo() in figure 9.11:

const SimpleCat * const FunctionTwo (const SimpleCat * const theCat);

Their description:

On line 46, itsAge is set using the accessor SetAge, and the result is printed on line 47. FunctionOne is not used in this program, but FunctionTwo() is called. FunctionTwo() has changed slightly; the parameter and return value are now declared, on line 36, to take a constant pointer to a constant object and to return a constant pointer to a constant object.

Is it possible anyone can break this down to make it easier to understand? Sorry to bother with "newbie" questions, but I'm committed to learning this language inside and out but it's kinda hard without a teacher.

It's dangerous in the sense that you might make a mistake inside a function you make.

Passing a regular pointer to a function means the function can mutiliate the object or primitive type that the pointer points to with almost no care whatsoever. Some functions need to alter the objects they are passed. For that, that's fine. Go for it.

The idea, though, is that if a function doesn't need to alter data, then it shouldn't be given the opportunity. It also improves readability to specifically denote parameters as being const when you don't want them to be messed with. If you notice the function takes a const pointer, you know right away that the function doesn't edit the pointer. That way, if you make a mistake inside the function, the compiler will warn you.

If the concept of disabling yourself seems like a foreign idea, think of it in terms of other items where you do the same thing. For example, using local variables instead of global ones. They improve readability, but they also protect you from mixing them up and using ones that are already being used by other functions. When you get to classes, you'll see that the identifiers public, protected, and private are all there to protect you from yourself (and others using your code from themselves). From the position of the computer, everything could be declared global or public or in this case with pointers, non-const, and all could be well. Since programmers are humans (well most of us for now ), and we tend to make mistakes, it's a good idea to employ safety items like this.

As for the prototype:

Code:

const SimpleCat * const FunctionTwo (const SimpleCat * const theCat);

The return type is this:

Code:

const SimpleCat * const

This means it returns a pointer to a SimpleCat object. The two const properties denote the following restrictions:

The pointer may not be made to point to another object (ie. the pointer itself is const).

Ok, looking at it from the perspective of avoiding the use of global variables, I kinda get it now. In the classes chapter, I did learn to separate the variables into the private section, but I guess I didn't think twice about why I was doing it exactly, your explanation sheds some light. They didn't touch on "protected" though, only private and public, so I'll have to look that up. Just got my Accelerated C++ book in the mail a few minutes ago, lol, hopefully this will clear things up completely so I can move past friggin' references/pointers.

Don't worry with protected for now. You'll come to it when you start reading about class inheritance.

As for the const keyword, do read about it. Particularly it's use with references and pointers. It's one of the most prevalent keywords you'll encounter and general advice is be pro-active about the constness of your declarations. That is, consider declaring everything const (variables, function parameters, member functions) unless you prove you shouldn't.

Originally Posted by brewbuck:Reimplementing a large system in another language to get a 25% performance boost is nonsense. It would be cheaper to just get a computer which is 25% faster.

>> I'm up to Ch.9 on this site
Besides the fact that that site doesn't look legal, it is from an old book that is teaching you some bad habits. Consider finding a newer book that teaches modern C++, or a new tutorial.

By the way, here's a trick to understand const with pointers. Read the line backwards:

const SimpleCat *const theCat

"theCat is a constant pointer to a SimpleCat that is constant".
-- This means, inside the function, you cannot change the pointer OR the object being pointed at.

This is functionally identical to:

SimpleCat const *const theCat

"theCat is a constant pointer to a constant SimpleCat"

That is, "const [typename] *" is the same as "[typename] const *" (the first way is the more common to write, but both are correct and equivalent).

Compare those to:

const SimpleCat *theCat

"theCat is a pointer to a SimpleCat that is constant".
-- This means, inside the function, you CAN change the pointer (to make it point to a different object) but CANNOT change the object being pointed at.

SimpleCat *const theCat

"theCat is a constant pointer to a SimpleCat ".
-- This means, inside the function, you cannot change the pointer, but you CAN change the object being pointed at.

You ever try a pink golf ball, Wally? Why, the wind shear on a pink ball alone can take the head clean off a 90 pound midget at 300 yards.

Now, when I look at GetHP(), I ask "does this function need to change any of the variables of this class?", and I answer "No" because it reads the variables but doesn't alter them. Likewise for GetMP().