C++ const correctness beats the .NET/Java alternatives

The C++ const keyword is a powerful tool. It basically allows you to pass a pointer or reference that can only be used to call const methods. ie: You can implement a mutable class and then pass an immutable reference to that class (the keyword also does other things, but that’s not what I’m writing about). This defines a much stronger contract. When a function asks for a pointer to an instance of Foobar it can promise that it will not change that object. For example:

#include <string>
#include <iostream>
 
// Here's a piece of a class with one const method and one non-const method
class Person
{
public:
	std::string getName() const { return name; }
	void setName(std::string newName) { name = newName; }
private:
	std::string name;
};
 
// This function asks for a references to a person but promises not to change the object
void doSomethingWithPerson(const Person &person)
{
	std::cout << person.getName(); // <-- this is fine
	person.setName("hello"); // <-- COMPILE ERROR
}
 
int main(int argc, char *argv[])
{
	Person myPerson;
	myPerson.setName("Foobar");
 
	doSomethingWithPerson(myPerson);
 
	return EXIT_SUCCESS;
}

I love code like this. When I call doSomethingWithPerson() I know for sure that it will not change the object (assuming I have properly labelled my const methods). This is an area where I generally think of languages like Java or C# as being superior to C++. We commonly assume that these higher level languages are better at protecting programmers from themselves (or other programmers) but here it is not the case. You can achieve a similar result by creating an immutable class, but what if you do want to change it in other cases? Maybe you want to pass an immutable instance to one function and a mutable instance to another. This can surely be implemented, but it likely involves creating a second class (maybe a read-only subclass) which is kind of a pain. In reality developers often do not bother to create read-only versions of classes where it is warranted, but they will take the time to put const where it is needed.

After a lot of time just working in .NET I have returned to doing some C++ programming on a hobby project. Suddenly I feel dirty when I go back to .NET and start passing objects as function parameters willy nilly without using a const reference. It really is amazing how programming in different languages can change the way you think.

2 Comments

  1. Ari Eisinger says:

    I recently realized that, due to RTTI in C#, a read-only subclass can be upcasted to its parent. In other words, the read-only version here does not hide the writeable version it’s supposed to protect. It seems to me therefore that what is required is not just a subclass but a wrapper class with a private member that just forwards the calls to the member. Yick!

    I agree that the lack of const references and const pointers in Java and C# is a big drawback.

  2. Ari Eisinger says:

    Sorry: I was thinking of using a read-only interface when I wrote the above, not a subclass. The actual type of the object could be determined using RTTI, and the read-only subclass could be upcast to its writeable superclass.

    With a read-only subclass, it seems to me that all you’d have to do would be to upcast and then you could use all the base class’s functions including the ones that modify the object.

    Anyway, it seems to require considerable gyrations to do this kind of thing, which in C++, as you say, can be done with the use of a single keyword.

Leave a Reply