Reputation: 16640
The const
qualifier on a method supposed to protect the data member from overwriting by mistake. If you have a data member which is a pointer then only the pointer is defended, the pointed value is not. Is it a flaw in the design of C++ or is there something fundamental thing it serves?
Here is a code which demonstrates the situation. Before reporting irrelevant bugs and style problems, please consider that its sole purpose is to demonstrate the above situation and to be short and straightforward in that.
#include <cstdio>
#include <cstdlib>
#include <cstring>
class Cat
{
public:
Cat(char const *name)
: _name(strdup(name))
{ }
~Cat(){ free(_name); }
void SetName(char const *name)
{
free(_name);
_name = strdup(name);
}
char const* GetName() const
{
_name[0] = 'P';
return _name;
}
private:
char *_name;
};
int main()
{
Cat c("lost+found");
c.SetName("Molly");
printf("%s\n",c.GetName());
return 0;
}
Compilation went without warnings and errors with the following command:
g++ -W -Wall -Wextra -pedantic -Os pmc.cpp -o pmc
The output of the resulting program was Polly
.
UPDATE Using pedantic char const *
instead of traditional const char *
Upvotes: 2
Views: 228
Reputation: 33106
The const qualifier on a method supposed to protect the data member from overwriting by mistake. If you have a data member which is a pointer then only the pointer is defended, the pointed value is not.
You have a mistaken perception of the purpose of the const
qualifier. It serves three purposes:
const
qualifier.The const
qualifier does not protect you as the author of some class from shooting yourself in your foot (or higher). What it does do is to protect you as the author of some class against someone else doing damage to your class and it allows the compiler to go to town with several optimizations that are not available in a non-const setting.
Upvotes: 3
Reputation: 361254
In the const
member function, the type of _name
becomes char * const
which means it is the pointer which is const, not the data which the pointer points to.
You seem to think that _name
becomes const char*
. No, the const
applies on the pointer
, not on the data it points to. So _name
has to become char * const
.
To minimize this confusion, I prefer the syntax T const
over const T
even though both are exactly same. Because if T
is char*
, then T const
would become char * const
, whereas const T
would become const char*
. While the former helps understanding, the latter complicates.
Upvotes: 2
Reputation: 36049
The fundamental thing served here is simply clarity. The pointer is a member of the class, its pointee is not: It is neither automatically destructed when the class is nor automatically constructed. It might be a wholly different object, so it should not necessarily be const when the class becomes const.
You are desiring something like std::string here, that is, additional semantics for the pointer - for example the guarantee that its contents will not change outside of your class.
Upvotes: 5