How can a change a const value?

Started by
12 comments, last by zipless 22 years, 2 months ago
OK i''ve never really used const''s before but i''ve decided that i could probably do with using them here and there but i also need to be able to modify their values. i''ll have something like this
  
class Csomeclass
   {
   public:
      const char *pointer;
      void ChangePointer(char *new);
   };
  
But what would i put in the function? /* Ignorance is bliss, then you go and spoil it by learning stuff */
/* Ignorance is bliss, then you go and spoil it by learning stuff */
Advertisement
Change a constant... Sounds like an oxymoron or a contradiction.

I wanna work for Microsoft!
[ GDNet Start Here | GDNet Search Tool | GDNet FAQ | MS RTFM [MSDN] | SGI STL Docs | Google! ]
Thanks to Kylotan for the idea!
A varible constant would make a better oxymoron.

I take it that means that it''s going to be a bit on the impossible side? I''m sure i read something somewhere about being able to change them, damm.



/* Ignorance is bliss, then you go and spoil it by learning stuff */
/* Ignorance is bliss, then you go and spoil it by learning stuff */
C++ is an extremely flexible language and yes(paradox aside) let you change const data.


  const int i = 3;const_cast<int>(i) = 4; //cast away constantness  



But your code design is defenitly wrong. Something in those lines is much better (and does not need to cast away constaness)

  class SomeClass{public:         const char* GetPoniter(void) const { return pointer; }         void ChangePointer( char* newPointer );private:          char* pointer;};  


Since GetPointer is inline, there is no cost associated with using it.
You could use const_cast to remove the constantness of a const.
But yeesh, that sort of defeats the purpose of using a const, doesn't it?
From what I've learned, it's not good prgramming practice to use const_cast, but it's there for you.

  const_cast <type> (expression);  


Edited by - Draxis on February 16, 2002 4:54:13 PM
Darn, beat me to it AND with a better example, Gorg
Ah, found out another way as well, i''m sure i''d tried using a cast before but i guess i can''t have.

const int var = 56;
int *change = (int *)&var
(*change) = 34;

I''ll just use that inside the ChangePointer func, cheers guys. I''ll keep the pointer publicas well, mainly becuase i find casting slightly less annoying than using functions to retrieve values.



/* Ignorance is bliss, then you go and spoil it by learning stuff */
/* Ignorance is bliss, then you go and spoil it by learning stuff */
quote:Original post by zipless
const int var = 56;
int *change = (int *)&var
(*change) = 34;


And what happens when the compiler notices you have this nice, const integer and decides to put it into read-only memory? Then your call *changed = 34 will hack up a nasty wet hairball, usually causing the program to crash or become unpredictable.

const_cast and the typical C cast to get rid of const are bad ideas not simply because they enforce good programming behaviours, but also sometimes because const data may not be modifiable, period. You should understand well where that data is going and what''s being done to it before you cast away const.

A better way to appear const, yet safely be able to modify things is with the mutable keyword. From the standard:

quote:
The mutable specifier on a class data member nullifies a const specifier applied to the containing class object and permits modification of the mutable class member even though the rest of the object is const.


Take an example -- we have an operation that is expensive to compute.

  class Does_Something_Expensive {private:  int expensive_operation() const ;public:  int get() const { return expensive_operation(); }};  


We''ve made things const, because we want to be safe and make sure people aren''t mucking with things they shouldn''t. That means normally that we can''t cache the value (within the class) without either removing const''s or casting it away somewhere.

But with mutable, we do this:

  class Does_Something_Less_Expensive {private:  int expensive_operation() const;  bool has_changed() const;public:  int get() const  {    if (has_changed()) {      cached_value = expensive_operation();    }    return cached_value;  }private:  mutable int cached_value;};  


And now we can cache the value, even in a const object, safely.


---- --- -- -
Blue programmer needs food badly. Blue programmer is about to die!
quote:Original post by zipless
Ah, found out another way as well, i''m sure i''d tried using a cast before but i guess i can''t have.

const int var = 56;
int *change = (int *)&var
(*change) = 34;

I''ll just use that inside the ChangePointer func, cheers guys.


The code that you''ve written above invokes undefined behaviour. You can cast away the const-ness of an object, but if that object began life as const, and you then change the object, it''s undefined behaviour. If you need to change it, then it''s not constant

quote:
I''ll keep the pointer publicas well, mainly becuase i find casting slightly less annoying than using functions to retrieve values.


If you ever work on large projects requiring good encapsulation, you might realise why this is not a good approach.

--
Very simple ideas lie within the reach only of complex minds.
quote:Original post by mossmoss
And what happens when the compiler notices you have this nice, const integer and decides to put it into read-only memory? Then your call *changed = 34 will hack up a nasty wet hairball, usually causing the program to crash or become unpredictable.

The compiler cannot do this to member variables though. You are allowed to change the value of member constants. If it was truely constant, you would also make it static. But don''t do what you did there zipless; it''ll succeed or fail at runtime depending on compilation options. (Release&Assume-No-Alias->Boom)

  class CArray{public:	CArray(int size) : m_Size(size) {}protected:	const int m_Size;};  



mutable does not apply to this case. Mutable lets member variable change when the object instance is constant. You cannot declare a variable const and mutable, that is an oxymoron.


The root of the problem is that you are using a char*, there is no correct C++ way to handle the situation due to this. Since it is a primative pointer, and since you allow them to change it, you may as well make it public.

If this is for a utility class, handling errors or some-such-thing, just make the pointer public. If it''s a regular class, change the names of everything to better reflect what''s really happening.

  class CAvatar{public:	const std::string& name(){return m_name;}	void ChangeName(std::string& newName);	void ChangeName(const char* const szNewName);protected:	std::string m_name;};  


It''s easily conceivable that you would need to do something other than update m_name upon a name change (say send it over the wire to everyone else playing the game).
- The trade-off between price and quality does not exist in Japan. Rather, the idea that high quality brings on cost reduction is widely accepted.-- Tajima & Matsubara

This topic is closed to new replies.

Advertisement