Thread: Need help with const pointers

  1. #1
    Registered User
    Join Date
    Aug 2007
    Posts
    6

    Unhappy 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.

  2. #2
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    I guess what I'm mainly confused about is, when passing by reference, what should determine if I need to make the parameters or return type constant? (that make any sense?) >_<

  3. #3
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    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:

    1. The pointer may not be made to point to another object (ie. the pointer itself is const).
    2. The data that the pointer points to is considered to be const.


    And so forth for the parameter.

  4. #4
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    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.

  5. #5
    (?<!re)tired Mario F.'s Avatar
    Join Date
    May 2006
    Location
    Ireland
    Posts
    8,446
    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.

  6. #6
    Registered User
    Join Date
    Jan 2005
    Posts
    7,366
    >> 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.

  7. #7
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    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.

  8. #8
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    ahh, so much easier to translate confusing prototypes when reading it backwards... thanks

  9. #9
    Registered User
    Join Date
    May 2003
    Posts
    1,619
    Oh, and as to the question about why make it const at all:

    Const correctness is a major goal of any program. When you make a function/method, when you're deciding what parameters you need, you should be deciding if they should be constant, too.

    For example, let's say I'm making a function that takes a char * string (I really SHOULD use std::string but this is just an example) and displays it somewhere:

    void displayString(char * str)

    I ask myself "do I need to change the contents of the string?" and I answer "No." so I make the string constant:

    void displayString(const char * str)

    Then I ask myself "do I need to change which string the pointer points at?" and I answer "No" again, so I make the pointer constant too:

    void displayString(const char * const str)


    There's one other key use of const, and that is in the methods of a class. For example, consider this simple class:

    Code:
    class GameCharacter
    {
         public:
              int GetHP();
              int GetMP();
    
         // Other stuff would go here...
    
    };
    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().

    I then change the class as follows:


    Code:
    class GameCharacter
    {
         public:
              int GetHP() const;
              int GetMP() const;
    
         // Other stuff would go here...
    
    };
    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.

  10. #10
    Registered User
    Join Date
    Aug 2007
    Posts
    6
    Ok that makes sense. Thanks, I'll probably be back for more help later

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Function template has already been defined
    By Elysia in forum C++ Programming
    Replies: 19
    Last Post: 04-14-2009, 10:17 AM
  2. The so annoying LNK2005... please help!
    By Mikey_S in forum C++ Programming
    Replies: 14
    Last Post: 02-01-2009, 04:22 AM
  3. Seg Fault in Compare Function
    By tytelizgal in forum C Programming
    Replies: 1
    Last Post: 10-25-2008, 03:06 PM
  4. fatal error LNK1104
    By DMH in forum C++ Programming
    Replies: 2
    Last Post: 11-16-2005, 03:46 AM
  5. Certain functions
    By Lurker in forum C++ Programming
    Replies: 3
    Last Post: 12-26-2003, 01:26 AM