Reputation: 189
I was reading Effective C++ book and it was talking about const correctness. The following code block was given:
class CTextBlock {
public:
...
char& operator[](std::size_t position) const // inappropriate (but bitwise
{ return pText[position]; } // const) declaration of
// operator[]
private:
char *pText;
};
The book was describing the potential issue with the above usage.
const CTextBlock cctb("Hello"); // declare constant object
char *pc = &cctb[0]; // call the const operator[] to get a
// pointer to cctb’s data
*pc = ’J’; // cctb now has the value “Jello”
What should be changed so that the assignment used in the last line is forbidden? The book didn't give a solution to the problem.
Thank you in advance for your help!
Upvotes: 0
Views: 67
Reputation: 869
This is a result of how the different parts of the code work. Const is supposed to provide guidance on the usage of objects and prevent programming mistakes. By using it you are telling other programmers that this value should not be changed. There isn't actually a way to ensure that the data isn't changed. this is because in c++ there are a number of ways of accessing the underlying memory and changing it. In the example you have given this is through the use of pointers.
Why is this you might ask. A great answer can be found at: http://www.cprogramming.com/tutorial/const_correctness.html The relevant section reads as follows:
First, why would you ever want to have the ability to change data in a class that's declared const? This gets at the heart of what constness means, and there are two ways of thinking about it. One idea is that of "bitwise constness", which basically means that a const class should have exactly the same representation in memory at all times. Unfortunately (or fortunately), this is not the paradigm used by the C++ standard; instead, C++ uses "conceptual constness". Conceptual constness refers to the idea that the output of the const class should always be the same. This means that the underlying data might change as long as the fundamental behavior remains the same. (In essence, the "concept" is constant, but the representation may vary.)
There are other ways to ensure that particular values remain constant ect that are harder to change or cannot be changed at runtime it that is your goal. You can also look at using #define or enum depending on what you are trying to achieve. I would recommend that before using any of them you research the differences as whilst they all perform similar functions the edge cases can have very different results and each on has different limitations. It is also worth noting that some developers have very strong opinions on which of these options should be used and when. For example is espoused that you should favour enum over #define for aa number of reasons as seen here: http://blogs.msdn.com/b/doronh/archive/2006/03/27/562502.aspx
A good description of the difference between enum and const can be found here: http://www.codeproject.com/Articles/4354/Enum-vs-Const
It is also worth noting that the way const works in c versus c++ is different so ensure when you are reading about how to use const and when that you are reading about its application in the correct language.
Upvotes: 2
Reputation: 2520
const char& operator[](std::size_t position) const
would prevent that, except if the user of the code used const_cast
to remove the const
.
Adding const
means that the data that the reference refers to can't be changed
Upvotes: 1
Reputation: 137960
The accessor should return a const char &
to restrict write-access to the return value.
Upvotes: 1