References and const in C++ with example programs

reference const

We use the const reference in C++ when we want to refer to a const type. It prevents changing the bounded object and also refers to a constant value (like 6, 27, 2.4 ..etc). In my previous article, I have explained the reference in detail if you had not read it, please check this link, “Introduction of the reference“.

 

Note: Here I am saying const reference but basically it is a reference to const because the reference is not an object, so we cannot make a reference itself const.

const int data = 10;

// Valid, rData bound to data it will but 
//cannot be used to change data
const int &rData = data;


//Invalid, because reference
//could not be const.
int & const rData = data;

 

Let’s compile the below example code to understand the above-described concept.

#include <iostream>

using namespace std;

int main()
{
    int data = 10;

    //Invalid, because reference
    //could not be const.
    int & const rData = data;

    return 0;
}

Output:  ‘const’ qualifiers cannot be applied to ‘int&’

 

In C++ you can write reference to const in two ways. For example, if I need to create a reference to const integer then I can write the expression in two ways. Most programmers like the first expression.

1. const int& rData = data;

2. int const &rData = data;

 

Note: Reference to const means that reference itself could not modify the referred object.

 

When we assign a CV (const and volatile) qualified object to an ordinary reference, we will get the error. This type of initialization is illegal and breaks the promise which has been done by the const object.

You can also see these articles:

See the below code, where I am assigning the const object to the ordinary reference and printing their value.

#include <iostream>

using namespace std;

int main()
{
    const int data = 10;

    int &rData = data; // rData bound to data

    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;

    return 0;
}

Output:

error: binding ‘const int’ to the reference of type ‘int&’ discards qualifiers.

A CV-qualified reference can refer to an ordinary object (not qualified by CV). It means a reference to const can refer to a non-const object. It is not an illegal statement and also does not break the rule because the reference to const only promises that it will not change the value of the referring object.

In the below example code, rData merely promises that the program won’t use rData to the value data.

#include <iostream>

using namespace std;

int main()
{
    int data = 10;

    int const &rData = data; // rData bound to data

    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;

    return 0;
}

Output:

const reference

 

If you will try to change the value of data, you will get the compile error.

#include <iostream>

using namespace std;

int main()
{
    int data = 10;

    int const &rData = data; // rData bound to data

    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;
    
    rData = 12; //change the value 
    
    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;
    
    return 0;
}

Output:

error: assignment of read-only reference ‘rData’

 

You know that an ordinary reference must match the type of object to which it refers. But a reference to const initializes from any expression that can be converted to the type of the reference.

See below initialization, where a reference to const integer pointing to a float variable.

float data = 6.27;

int const &rData = data; // rData bound to data

 

The initialization is valid because the compiler automatically creates a temporary integer object. It is an unnamed object which binds to the reference to const integer. So after creating the temporary object, the above initialization is looked like the below expression.

float data = 6.27; //float variable

const int temp = data; // create a temporary const int from the float

const int &rData = temp; // bind rData to that temporary

 

Let’s see some example code and their compilation result,

#include <iostream>

using namespace std;

int main()
{
    float data = 6.27; //float variable

    int const &rData = data; // rData bound to data

    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;

    return 0;
}

Output:

 

When binding character array to rData,

#include <iostream>

using namespace std;

int main()
{
    char data[] = "Aticleworld"; //char array

    int const &rData = data; // rData bound to data

    cout <<"data = " << data << endl;
    cout << "rData = " << rData << endl;

    return 0;
}

Output:   error: invalid conversion from ‘char*’ to ‘int’.

 

A reference with const is useful when you need to pass an object in the function without making a copy of the object with the guaranty that function will not change anything to passed object. It will save your stack memory and good thing is that you can also pass a non-const object to the function.

#include <iostream>

using namespace std;

//function to print integer value
void printData(const int &data)
{
    cout << "data = " << data << endl;
}

int main()
{
    int a = 10; //non-const int
    const int b =20; //const int

    //print a
    printData(a);

    //print b
    printData(b);

    return 0;
}

Output:

non const object to reference

 

If you want to learn C++11 from scratch then you can follow this course trial is free.

Your free trial is waiting.

 

 

typedef with reference to const

We can use the typedef with reference and create a new reference type.

typedef  int & refToInt;

In the above expression, the newly created type refToInt is a reference to int. When we will create an identifier using the refToInt then the type of the identifier would be a reference to int.

#include <iostream>

using namespace std;

typedef int& refToInt;


int main()
{
    int data = 24;

    refToInt rData = data;

    cout << rData << endl;

    return 0;
}

Output: 24

 

You can also see the below article:

But here you need to remember one thing if you will use newly reference type ( created by the typedef) with CV qualifier, the effect of the CV  qualifier will not reflect on the reference identifier. See the below code,

In which I have used const with newly type but you can see the effect of const is not reflect on the rData and it is not initialized by a non-const object. In other words, you can say that the type of rData is “lvalue reference to int”, not “lvalue reference to const int”.

#include <iostream>

using namespace std;

typedef int& refToInt;


int main()
{
    const int data = 24;

    const refToInt rData = data;

    cout << rData << endl;

    return 0;
}

Output: error: binding ‘const int’ to reference of type ‘refToInt {aka int&}’ discards qualifiers|

If I will remove the const with data, you can see code will compile properly and you will get the proper result.

#include <iostream>

using namespace std;

typedef int& refToInt;


int main()
{
    int data = 24;

    const refToInt rData = data;

    cout << rData << endl;

    return 0;
}

Output: 24

 

Instead of using CV qualifier separately with new reference type (created by typedef) (because ill-formed), you can use the CV qualifier with typedef at the time of creating a new reference type.

typedef const int& refToInt;

 

See the example code,

#include <iostream>

using namespace std;

typedef const int& refToInt;


int main()
{
    const int data = 24;

    const refToInt rData = data;

    cout << rData << endl;

    return 0;
}

 

Recommended Post

 



Leave a Reply

Your email address will not be published. Required fields are marked *