Search

8.10 — Const class objects and member functions

In the lesson on passing arguments by reference, we covered the merits of passing function parameters as const variables. To recap, making variables const ensures their values are not accidentally changed. This is particularly important when passing variables by reference, as callers generally will not expect the values they pass to a function to be changed.

Just like the built-in data types (int, double, char, etc…), class objects can be made const by using the const keyword. All const variables must be initialized at time of creation. In the case of built-in data types, initilization is done through explicit or implicit assignment:

In the case of classes, this initialization is done via constructors:

If a class is not initialized using a parameterized constructor, a public default constructor must be provided -- if no public default constructor is provided in this case, a compiler error will occur.

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 constness of the object. This includes both changing member variables directly (if they are public), or calling member functions that sets the value of member variables:

All three of the above lines involving cSomething are illegal because they violate the constness of cSomething by attempting to change a member variable or calling a member function that attempts to change a member variable.

Now, consider the following call:

Surprisingly, this will cause a compile error! This is because const class objects can only call const member functions, GetValue() has not been marked as a const member function. A const member function is a member function that guarantees it will not change any class variables or call any non-const member functions.

To make GetValue() a const member function, we simply append the const keyword to the function prototype:

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

Const member functions declared outside the class definition must specify the const keyword on both the function prototype in the class definition and on the function prototype in the code file:

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_nValue. This will cause a compiler error.

Note that constructors should not be marked as const. This is because const objects should initialize their member variables, and a const constructor would not be able to do so.

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 const version of GetValue() returns a const reference, whereas the non-const version returns a non-const reference.

Let’s take a look at making our date class member functions const so they can be used with const Date objects:

The only non-constructor member functions that do not modify member variables (or call functions that modify member variables) are the access functions. Consequently, they should be made const. Here is the const version of our Date class:

The following is now valid code:

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

23 comments to 8.10 — Const class objects and member functions

  • abhi4556

    const class objects can only call const member functions
    Note: that constructors should not be marked as const. This is because const objects should initialize their member variables, and a const constructor would not be able to do so.

    I think the above lines contradict each other. Please explain.

  • wisemary_stephen

    Hi,
    I am passing a class object by refernce into a function which r eturns a class object
    I have a header file, client cpp file and main file.

    header:
    class MFRACTION
    {
    public:

    void set(int numer, int denom);

    double toDouble() const;
    QString toString() const;

    MFRACTION add(const MFRACTION& );
    MFRACTION (const MFRACTION& frr);
    // MFRACTION & operator=(const MFRACTION other);
    ~MFRACTION ();
    private:
    int n;
    int d;

    MFRACTION.CPP:
    void MFRACTION::set(int numer, int denom){
    n = numer;
    d = denom;
    }
    MFRACTION::MFRACTION(const MFRACTION &frr):n(frr.n),d(frr.d){}

    double MFRACTION::toDouble()const{
    return 1.0 * n/d;
    }

    QString MFRACTION::toString()const
    {
    return QString("%1/%2").arg(n).arg(d);
    }

    MFRACTION add(const MFRACTION&)
    {
    int n;
    int d;
    MFRACTION frr;
    return MFRACTION ((n * frr.d)+ (d + frr.n),d*frr.n);
    }

    MAIN.CPP:
    int main(){
    MFRACTION f1, f2,f3;

    QTextStream cout (stdout);
    QTextStream cin(stdin);

    int m;

    f1.set(7,1);
    f2.set(5, 8);
    f3 = f1.add(f2);

    cout << "The first fraction is" << f1.toString() << endl;
    cout << "The second fraction is" << f2.toDouble() << endl;
    cout<< "after calling"<< f3.toString()<> m;
    return 0;

    THE ERROR I M GETTING IS n.d and frr are private and not declared in this scope in the add function that i am calling in Mfraction.cpp file.

    This program though written in Qt It uses all C++ coding.
    Please help me what is wrong in this.
    Mary

  • April

    hi Alex,

    I don't get how you have overloaded the functions, cause I remember you've said functions can be overloaded only if their signature (type/number of parameters) is diffrent which is not the case here

    const int& GetValue() const { return m_nValue; }
    int& GetValue() { return m_nValue; }

  • gans

    Hi Alex,
    I strange thing about Const object:

    lets say I have a class A, and no default or parameterised constructor. but in the main I try to create a const object of this.

    const A a;
    it does not throw any compilation error.
    but if i do it for built in datatype like const int i, it tells us initialise at the time of creation.

    Thanks,

  • Yashar

    Hi
    Why do you set the return type of the GetValue() a reference in the below class?
    I can not understant it, because m_nValue which GetValue() returns it, is not a reference.
    class Something
    {
    public:
    int m_nValue;

    const int& GetValue() const { return m_nValue; }
    int& GetValue() { return m_nValue; }
    };

  • hai

    const and volatile specifier for the function definition is used for the function overload.

  • Sachin

    Alex,

    It would be great if you could answer Anand's query since I also had the same doubt when I read the tutorial.
    "Overloading the function doesn’t depend on Return type of function,
    Overloading the function only depend on Signature of fucntion(i.e. no of args or types of args.)

    Here Overloading function GetValue

    const int& GetValue() const and
    int& GetValue()

    In this case, how does the compiler do name mangling?

  • Vikas

    Ahh... I almost gave in for the last part of this section.... Though confusing at the same time very simple explanation... may be for the first timers its little terrifying..

    Hope i will come back to this section again :(

Leave a Reply

You can use these HTML tags

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">