Developers often wish to access variables that have the same name, but belong to different scopes. If the scope of the referenced variable is not explicitly resolved, computers simply access the innermost variable, as shown below:
#include <iostream>using namespace std;int x = 10; //Global variable x declaredint main() {int x = 8; //Local variable x declaredcout << "Value of x is " << x << endl;return 0;}
In the above snippet, the main function accessed the local instance of variable x. But, what if we wanted to access the global instance instead? In this instance, the scope resolution operator would come in handy.
The scope resolution operator (::) specifies the scope of a referenced identifier. This operator has many uses in C++. Let’s take a look at some of them.
1. Distinguishing a global variable from a local variable of the same name
As discussed earlier, sometimes we want to access a global variable in the vicinity of a local variable with the same name. The use of the resolution operator in the code below illustrates a simple solution.
#include <iostream>using namespace std;int x = 10; //Global variable x declaredint main() {int x = 8; //Local variable x declared//Accessing global x using ::cout << "Value of global x is " << ::x << endl;cout << "Value of local x is " << x << endl;return 0;}
Note that in the above example, ::
is used as a unary operator. In the coming examples, we will see how it can be used as a binary operator as well.
2. Defining a function outside the class it belongs to
The scope resolution operator also enables us to define a function outside the class it is declared. This is shown below.
#include <iostream>using namespace std;class Car {public:void honk(); //Function declared inside class};void Car::honk() { //Function defined outside class using ::cout << "Beep! Beep!" <<endl;}int main() {Car ferrari;ferrari.honk();return 0;}
3. Distinguishing between identifiers coming from different ancestor classes
Multiple inheritances can sometimes lead to ambiguity if multiple ancestor classes contain variables that share the same name. Scope resolution can solve this too.
#include <iostream>using namespace std;class Mother {protected:int age;public:Mother() { //Constructor definedage = 32;}};class Father {protected:int age;public:Father() { //Constructor definedage = 34;}};class Child : public Mother, public Father { //Multiple inheritancepublic:string name;Child(string name) //Constructor defined{this->name=name;}void print_parent_ages(){//Using :: to access the age variables of both parent classescout << name<< "'s mother's age is " << Mother::age << endl;cout << name << "'s father's age is " << Father::age <<endl;}};int main() {Child Sam("Sam");Sam.print_parent_ages();return 0;}
4. Accessing a class nested inside another
The “::” can also help us access classes nested inside other classes, as shown below:
#include<iostream>using namespace std;class Outer_class {public:int x;Outer_class() { //Outer constructor definedthis->x = 7;}class Inner_class { //Declaring a class inside anotherpublic:int x;Inner_class() { //Inner constructor definedthis->x = 8;}};};int main() {Outer_class outer;//Using :: to access inner class from outer classOuter_class::Inner_class inner;cout << "Outer x: " << outer.x << endl;cout << "Inner x: " << inner.x << endl;return 0;}
5. Accessing a class’s static variables
The binary scope resolution operator can also be used to define, and later access, a class’s static variables, as shown below:
#include <iostream>using namespace std;class Person {public:static int x;};int Person::x = 4; //Person's static variable defined using ::int main() {int x = 14; //Local variable defined//Person's static variable defined using ::cout << "Static variable x: " << Person::x << endl;cout << "Local variable x: " << x << endl;return 0;}