C++ const Correctness

Objects declared const have a modified type whose value cannot be
changed; they are read-only. For built-in types declared as
const, this means that once initialized the compiler refuses to
alter their values:

Usually, the const modifier comes immediately before the object it
modifies. For example:

const int ZERO = 0;
const std::string msg( "Hello, World" );

When applied to pointers, special attention should be paid to the
placement of const. A pointer is a variable itself, so the
placement of const often determines whether it applies directly to
the pointer, to the object pointed to or to both. For example:

Above, str1 is a pointer to a constant string. The const modifies
the type std::string. Because there is no const * construct in
C++, str2 also is a pointer to a constant string. Both str1 and
str2 point to constant strings; therefore, it is impossible to
alter the value of the strings they point to. However, it is possible
to alter the pointers themselves, and indeed the str2 pointer is
changed so that it points to another std::string. Deciphering these
declarations can be difficult unless you read them backwards, from
right to left. For example, the declaration of str1 can be read
from right to left as "str1 is a pointer to a std::string which is
const". And str2 can be read as "str2 is a pointer to a constant
std::string". Although they are written differently, these declarations
describe pointers of a similar type.

The str3 variable demonstrates a pointer that is constant itself; the pointer value cannot be modified, although the argument pointed
to can. It can be read as "str3 is a constant pointer to a
std::string". Finally, str4 is the most extreme example. It can be
read as "str4 is a constant pointer to a std::string which is const";
neither the pointer nor the string can be modified.

Const Member Functions

The const modifier becomes a part of the object type and also can be
applied to user-defined types:

Because Invoice::giveDiscount() has the potential to alter the internal state
of the object, the compiler refuses to let you invoke this member
function on i, which is declared as const. However, individual
member functions themselves can be declared const, which tells the
compiler that those member functions do not alter the internal state
of the object and therefore are safe to invoke on const objects.
For example:

C++ directly supports const as a language feature, so the
compiler provides free compile-time checking of const objects. With
properly designed interfaces that utilize const member functions,
you are free to declare and use constant user-defined objects--only
the const interface of those objects will be available. Designing
interfaces that are const correct essentially boils down to
declaring const member functions wherever possible. And these
const member functions should be included early on in the design of
your classes. Trying to retrofit them later often leads to a
cascading effect throughout the applications that use your classes.
It is much better to use const early and often in your designs.

When designing const member functions, you may encounter a situation
in which altering the internal state of the class is necessary.
For example:

In the above example, the value of sumCache cannot be altered, because
CustomerInvoice::sum() is declared to be const. However, we really
do want to cache the value for later use; so how can this be done?
The answer is "with the mutable keyword", which is the converse of
const when applied to member variables. For example,
CustomInvoice can be corrected as follows:

Now, the compiler allows sumCache to be modified within the
CustomerInvoice::sum() const member function because sumCache was
declared to be mutable. The mutable keyword instructs the
compiler to accept changes to the variable declared with it, even in
const member functions.

Dereferencing a null pointer produces undefined behavior. So you are not so much 'creating an invalid reference' as you are invoking undefined behavior (by dereferencing a null pointer).

Your compiler may accept this program, however at run time it should crash when you dereference 'x'. If it does not, that does not mean you are creating an invalid reference since any behavior after this point is undefined.

Was just reading Scott Meyer's 2nd ed of Effective C++... It's great to get another walk through on this topic. Articles like this are the best... I don't have to know huge amounts about c++ to learn this one part. Please do more articles like this!!!

But doesn't all this messing around with const really show that C++ is not the greatest language for object-oriented development.Most people are just content to accept this less than adequate language as if there is nothing better.No one to blame but yourselves. Try reading about a number of other.programming language architectures and then, if you are bright enough, you'll realize there are some compelling alternatives available.

By the way, C++ is not a pure object-oriented language.It is a hybrid. True object-oriented languages typically consider all types as objects, not just those types that are instances of classes

And contrary to the author's point of view, the most fundamental unit of development in C++ is not the class. Classes are extensions of structures in C++.

I'm assuming the author is a Java programmer. It always seems like those people that use other languages like java forget where they came from. If you go read those other programming langauges most the time you will find "...uses a C++ like syntax".

Anyways without going into a fifty page rant, it pretty much boils down to this. If you don't like C++ don't use it... unless of course you need to write a driver for your new unsupported sound card.. opps can't do that in java.. sorry.. but you should be ok writting that next high speed 3d shoot em up.. opps.. can't realy do that in java either..

Don't assume. It makes you look less intelligent, especially when you can't spell "oops" correctly. Most people that complain about the speed of Java are simply bad programmers. C and C++ have the brute force to let bad programmers write fast code, where Java will penalize the programmer who really doesn't know how to program, which is generally the case. Just because Java is easy to program, it doesn't mean that it easy to program correctly.

And actually, you can write high speed 3d graphics in Java, just don't try it with Swing or AWT. Unsubstantiated conceits like this betray the meaning of what you were trying to say with your reply..

Despite the author's commments and even Bjarne Stroustrup's various digs at his own language, C++ can be an elegant and effective language, both in it's C and object-oriented forms. Cornering yourself into a single language because of some herd mentality that it is just "better" is just plain silly. Each has it's strengths and weaknesses that should be evaluated for a project, and hopefully the "best" for that project is used.

True object-oriented languages typically consider all types as objects, not just those types that are instances of classes

Even true object-oriented languages like Java do not treat all types as objects. They have basic data types like int and char. Every language eventually has to be compiled down to machine language and machine language does not recognize objects. Each programming language has its strengths and weaknesses.

That's true, although the standard Java library does re-implement primitives as classes.

Of course, what takes C++ out of the "pure object-oriented language" category is the fact that it doesn't force all functions to be members of classes, and ultimately uses a non-member function as the program entry point. It has nothing to do with whether the language has primitives (the only languages I've used that *kind of* don't are high-level languages that use scalars -- which are basically primitives.) The original poster simply didn't know what he/she was talking about.

Oh, and by the way, 'const' is a reserved keyword in Java, they just don't use it for anything (yet) to my knowledge. I do know there has been talk to add similar functionality to that language.

Anyways, this guide was exactly what I was looking for when I typed '"c++" +const' into google. Great article!

By the way, C++ is not a pure object-oriented language.It is a hybrid. True object-oriented languages typically consider all types as objects, not just those types that are instances of classes.

Incorrect. Though C++ is a hybrid, and this is a strength because it allows the user to choose the paradigm to employ, an object can be of any type. Objects that are of a class-type are not special in this way. You might only consider arrays not to be first-class objects (but they are objects, just apply sizeof to one), and you can use features like std::vector or boost::array if find that a hindrance.

It is very probable that a container class such as vector is implemented with copy-on-write sharing, and that the non-const version of begin() would already cause such a copy (a detach) to happen. I have thus started to maximise the const usage in my applications. I will go to moderate pains to be able to declare a temporary variable const, e.g.:

The pain becomes moderate if you start to nest ternary operators, which can be done surprisingly readable, but there comes always a point where you want to refactor the mess into a function of its own.

Using const temps also forces you to use proper scoping and init-on-declaration, which is a worthwhile goal in itself (it saves ctor and assignment operator calls).

Trending Topics

Upcoming Webinar

Getting Started with DevOps - Including New Data on IT Performance from Puppet Labs 2015 State of DevOps Report

August 27, 2015
12:00 PM CDT

DevOps represents a profound change from the way most IT departments have traditionally worked: from siloed teams and high-anxiety releases to everyone collaborating on uneventful and more frequent releases of higher-quality code. It doesn't matter how large or small an organization is, or even whether it's historically slow moving or risk averse — there are ways to adopt DevOps sanely, and get measurable results in just weeks.