8.10 — Const class objects and member functions

In lesson 2.9 -- Const, constexpr, and symbolic constants, you learned that fundamental data types (int, double, char, etc…) can be made const via the const keyword, and that all const variables must be initialized at time of creation.

In the case of const fundamental data types, initialization can be done through copy, direct, or uniform initialization:

Const classes

Similarly, instantiated class objects can also be made const by using the const keyword. Initialization is done via class constructors:

Once a const class object has been initialized via constructor, any attempt to modify the member variables of the object is disallowed, as it would violate the const-ness of the object. This includes both changing member variables directly (if they are public), or calling member functions that set the value of member variables. Consider the following class:

Both of the above lines involving variable something are illegal because they violate the constness of something by either attempting to change a member variable directly, or by calling a member function that attempts to change a member variable.

Const member functions

Now, consider the following line of code:

Perhaps surprisingly, this will also cause a compile error, even though getValue() doesn’t do anything to change a member variable! It turns out that const class objects can only explicitly call const member functions, and getValue() has not been marked as a const member function. A const member function is a member function that guarantees it will not modify the object or call any non-const member functions (as they may modify the object).

To make getValue() a const member function, we simply append the const keyword to the function prototype, after the parameter list, but before the function body:

Now getValue() has been made a const member function, which means we can call it on any const objects.

For member functions defined outside of the class definition, the const keyword must be used on both the function prototype in the class definition and on the function definition:

Futhermore, any const member function that attempts to change a member variable or call a non-const member function will cause a compiler error to occur. For example:

In this example, resetValue() has been marked as a const member function, but it attempts to change m_value. This will cause a compiler error.

Note that constructors cannot be marked as const. This is because constructors need to be able to initialize their member variables, and a const constructor would not be able to do so. Consequently, the language disallows const constructors.

It’s worth noting that a const object is not required to initialize its member variables (that is, it’s legal for a const class object to call a constructor that initializes all, some, or none of the member variables)!

rule: Make any member function that does not modify the state of the class object const

Const references

Although instantiating const class objects is one way to create const objects, a more common way is by passing an object to a function by const reference.

In the lesson on passing arguments by reference, we covered the merits of passing class arguments by const reference instead of by value. To recap, passing a class argument by value causes a copy of the class to be made (which is slow) -- most of the time, we don’t need a copy, a reference to the original argument works just fine, and is more performant because it avoids the needless copy. We typically make the reference const in order to ensure the function does not inadvertently change the argument, and to allow the function to work with R-values (e.g. literals), which can be passed as const references, but not non-const references.

Can you figure out what’s wrong with the following code?

The answer is that inside of the printDate function, date is treated as a const object. And with that const date, we’re calling functions getYear(), getMonth(), and getDay(), which are all non-const. Since we can’t call non-const member functions on const objects, this will cause a compile error.

The fix is simple: make getYear(), getMonth(), and getDay() const:

Now in function printDate(), const date will be able to successfully call getYear(), getMonth(), and getDay().

Overloading const and non-const function

Finally, although it is not done very often, it is possible to overload a function in such a way to have a const and non-const version of the same function:

The const version of the function will be called on any const objects, and the non-const version will be called on any non-const objects:

Overloading a function with a const and non-const version is typically done when the return value needs to differ in constness. In the example above, the non-const version of getValue() will only work with non-const objects, but is more flexible in that we can use it to both read and write m_value (which we do by assigning the string “Hi”).

The const version of getValue() will work with either const or non-const objects, but returns a const reference, to ensure we can’t modify the const object’s data.

This works because the const-ness of the function is considered part of the function’s signature, so a const and non-const function which differ only in const-ness are considered distinct.


Because passing objects by const reference is common, your classes should be const-friendly. That means making any member function that does not modify the state of the class object const!

8.11 -- Static member variables
8.9 -- Class code and header files

78 comments to 8.10 — Const class objects and member functions

  • ankit mahlawat

    I have similar doubt(as of jules) but with const part of getvalue function i.e.

    now when you call its function in main i.e

    it will return const string refrence but you are not taking that refrence anywhere in any const variable isn’t it wrong. I think it should be done like this

  • Rohde Fischer

    Wouldn’t this be a good place to cover the advantages of immutability, and how immutability heavily improves ones design, especially in regard to concurrency (even though you haven’t covered that yet)? And also cover the tradeoffs with immutability, for instance some people might be coding for embedded devices, where the cost of extra instances etc. might not be acceptable

  • Jules


    I don’t understand how this:

    can be called with:

    With the assignation of a value?


    • Alex

      getValue() returns a reference to m_value, so the return value can be treated as if it were m_value itself. So something.getValue() = “Hi” is essentially the same as something.m_value = “Hi”.

  • ujjwal jain

    Hi Alex,
    It is mentioned there we can not create const constructor  and const object can only call const function so when we create a object like ex: const Example objEx;  how this is able to initialize via non const constructor?

    • Alex

      Const variables still need to be initialized:

      Const classes are no different -- when you create a const object, the constructor has to be non-const so you can initialize the class to whatever value is appropriate.

      When a class object is created, the constructor is called implicitly (by the code that creates the object) -- it’s smart enough to know it should always invoke a non-const constructor.

  • rara

    hi Alex,

    there is no return in getValue() function but member variable "m_something" has value "hi",
    how can "m_something" has value ?, is this default assignment to the first member variable ?,

    -sorry bad english-

    • Alex

      If your compiler doesn’t prevent this (which it really should), the C++ standard has this to say: “Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.”

  • Hi, could you tell me why we need to use const twice in the const function?

    I conjecture that the second const (right before the function body) is what distinguishes the const function from the non-const function during method overloading but I do not understand the use of the first const (right before the function type).

    • Alex

      The leftmost const is part of the function’s return type, indicating that a const reference is returned. The rightmost const indicates that the member function itself is const. This means it won’t change the state of the object, and can be called by const objects of the class.

Leave a Comment

Put C++ code inside [code][/code] tags to use the syntax highlighter