C++ const Correctness

Using const correctly in order to future-proof today's class designs.
Conclusion

As a general principle of class design, encapsulation is good. It reduces the complexity of your code and reduces the number of possible interactions between classes. Using const member functions increases encapsulation by restricting the ways in which an object can be used in certain circumstances, particularly when objects are passed by constant reference to functions or member functions. The const modifier is evaluated at compile-time, so it costs nothing at run-time.

You now have the tools required to make your classes const correct. A proper const interface allows the compiler to do a lot of type-checking work for you in situations where constant objects are used. Without a const interface, the speed and encapsulation benefits of constant user-defined types is lost. A class designed without const member functions hamstrings those who would use the class, as there otherwise would be no way to use the class when objects of its type are passed by const references. As shown above, users of your classes have good reason to manipulate them in this way. Being const correct then comes full-circle, as only the const interface to your class is available in these situations.

Many programming practices and conventions are available that can improve code in all types of ways. The notion of const, though, is supported directly by the language and provides a free compile-time mechanism to better encapsulate the concepts within your programs as classes. The most fundamental unit of design in C++ is the class. Concise, simple and const correct class interfaces improve portability, add flexibility and provide a foundation for extending your design to previously unforeseen purposes.

The public interfaces of your classes are the ones used by developers, including yourself. Interfaces that exploit the value of const modifiers promote looser coupling between classes by further limiting the public interface. Looser coupling provides a better foundation for expanding and re-tooling your classes for future situations. Designing for future changes is essential, and const correctness is an important principle to follow in future-proofing your class designs today.

Dave Berton is a professional programmer. He can be reached at mosey@freeshell.org.

______________________

Comments

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Thanks

Henning's picture

I just wanted to thank you for this great text, too.
I read lots of tutorials and also a big book about C++ and never got behind the const magic (worse: I misunderstood it!).

This finally made my mind clear about const, references and these things.
Very good work!

Great Article

Argonaut's picture

First, thanks for the article. I found it very informitive and well thought through. So much on the iNet today is certainly less than what we would hope for. (Thanks for putting the time into this)

Second, I appologize for my Rambunctious colleagues. (Assuming they are in the profession of Software Engineering and not just college hackers)

Keep up the great work.

Cheers

Re: C++ const Correctness

Anonymous's picture

Great article! :-)

invalid references

Anonymous's picture

> You never can create an invalid reference,
> so f() does not need to worry about invalid pointers.

How about this :

int* x = NULL;
int& rx = *x;

Isn't rx an invalid reference ?

I saw this many times "there are no invalid references" ... it's simply false.

Re: invalid references

Anonymous's picture

Dereferencing a null pointer yields undefined behaviour, so your example is flawed.

Re: invalid references

Anonymous's picture

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.

Re: invalid references

Anonymous's picture

Correct!

Especially bastardish in multi threaded applications and dynamically created objects.

Sometimes it is really easier to just use pointers because you can at least check if they are != 0...

Re: invalid references

Anonymous's picture

No, since using pointers in function interfaces is ambiguous at best. For example,

void foo( int* x );

Here, there is no indication whether nulls are allowed or not. If they are, who is at fault: the calling function or the called function? Using references removes all ambiguity:

void foo( int& x );

The fewer pointers you have in your interfaces, the less time you will spend running around chasing nulls.

Effective C++

Anonymous's picture

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!!!

Thanks!

Re: C++ const Correctness

Anonymous's picture

That's all fine and well.

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++.

Use a better langauge and these 'const' issues are just noise.

Go figure..

Re: C++ const Correctness

Anonymous's picture

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..

Re: C++ const Correctness

Anonymous's picture

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.

Re: C++ const Correctness

Anonymous's picture

FORTRAN RULES FOREVER!

Re: C++ const Correctness

Anonymous's picture

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.

True Object Oriented Languages

David Ash's picture

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!

Re: C++ const Correctness

Anonymous's picture

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.

Re: C++ const Correctness

Anonymous's picture

> 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++.

Incorrect. In C++, structures are classes, ones with all members defaulted to having public accessability. This is the only difference between a class and a struct.

Re: C++ const Correctness

Anonymous's picture

Bases and members both.

Re: C++ const Correctness

Anonymous's picture

...as if there is nothing better... if you are bright enough, you'll realize there are some compelling alternatives available.

Thats interesting, if those who could program well while having to deal with all these const are not "bright", then what does it make those who cannot handle it?

Re: C++ const Correctness

Anonymous's picture

An important issue has been left out: overloading of methods on const. This is used extensively in the STL:

class vector {
//...
iterator begin();
const_iterator begin() const;
//...
};

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.:

const std::vector v = someBool ? someFunc() : someOtherFunc() ;

instead of

std::vector v;
if ( someBool )
v = someFunc();
else
v = someOtherFunc();

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).

Webinar
One Click, Universal Protection: Implementing Centralized Security Policies on Linux Systems

As Linux continues to play an ever increasing role in corporate data centers and institutions, ensuring the integrity and protection of these systems must be a priority. With 60% of the world's websites and an increasing share of organization's mission-critical workloads running on Linux, failing to stop malware and other advanced threats on Linux can increasingly impact an organization's reputation and bottom line.

Learn More

Sponsored by Bit9

Webinar
Linux Backup and Recovery Webinar

Most companies incorporate backup procedures for critical data, which can be restored quickly if a loss occurs. However, fewer companies are prepared for catastrophic system failures, in which they lose all data, the entire operating system, applications, settings, patches and more, reducing their system(s) to “bare metal.” After all, before data can be restored to a system, there must be a system to restore it to.

In this one hour webinar, learn how to enhance your existing backup strategies for better disaster recovery preparedness using Storix System Backup Administrator (SBAdmin), a highly flexible bare-metal recovery solution for UNIX and Linux systems.

Learn More

Sponsored by Storix