Consider the following code:
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?
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;
}
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?