C++, composition, and const

Discussion in 'Mac Programming' started by rinseout, Aug 10, 2005.

  1. rinseout macrumors regular

    Joined:
    Jan 20, 2004
    #1
    Consider the following code:
    Code:
    #include <iostream>
    using namespace std;
    
    class Dog {
    private:
      bool happy;
    public:
      Dog() { happy = false; return; }
      void receive_food() { happy = true; return; }
      bool is_happy() const { return happy; }
    };
    
    class DogOwner {
    private:
      Dog* fido;
    public:
      DogOwner() { fido = new Dog(); }
      ~DogOwner() { delete fido; }
      void feed_dog() const { fido->receive_food(); return; }
      bool is_fido_happy() const { return fido->is_happy(); }
    };
    
    int main() {
      DogOwner sucker;
      cout << "Before feeding, owner's dog is " << (sucker.is_fido_happy() ? "happy" : "not happy" ) << endl;
      sucker.feed_dog();
      cout << "After feeding, owner's dog is " << (sucker.is_fido_happy() ? "happy" : "not happy" ) << endl;
      return 0;
    }
    
    I find it strange that the compiler won't complain even though Dog::receive_food() is not declared const and DogOwner::feed_dog() is. So by calling DogOwner::feed_dog(), a const method, you can change the returned value of DogOwner::is_fido_happy(), also a const method, which breaks the semantics of what you expect "const" methods to do (specifically, that they don't act as mutators of the class).

    Just as I'm typing this, I figured that the reason is that DogOwner::feed_dog() doesn't change the Fido* (an address), but the instance it is pointing to. I know that if the DogOwner class had a Dog& and not a Dog*, that the compiler would complain.

    Still, I think it's a bit fishy that you can "bend" the semantic rules of const methods this way, if not their strict meaning.

    My question is: does the language standard allow this, or does my compiler not deal with const methods properly? It seems like a const method should only be allowed to call the const methods of its members, even if you are accessing the members via a pointer to them.

    Put another way, shouldn't the const methods of DogOwner only be allowed to do things that are allowed for "const Dog* const"s, and not just "Dog* const"s?
     
  2. superbovine macrumors 68030

    superbovine

    Joined:
    Nov 7, 2003
    #2
    placing a const in a method without the object being declared a const will only tell the compiler to check to see if that specific method modifies the object. In your case, none of the methods modify the object per say because Dog* fido address does not change just the data that it points to. However, making fido a const will avoid letting anything from changing the object.

    also note, a const can be changed through an alias pointer.
     
  3. rinseout thread starter macrumors regular

    Joined:
    Jan 20, 2004
    #3
    Thanks. I think I forgot about this, and now I know (again). I have grown to rely on const a lot to protect myself from stupid mistakes, but I guess this is all a lesson that you can still manage to change consts if you like.
     

Share This Page