How to access a global variable within a local scope?

user3080728 picture user3080728 · Dec 8, 2013 · Viewed 29.7k times · Source

This is my code

#include <iostream>
using namespace std;
int x = 5;
int main()
{
    int x = 1;
    cout << "The variable x: " << x << endl;
}   

I get as output 1, but I would like to have 5, as in accessing the global x variable.

Is this possible?

Answer

KodingKid picture KodingKid · Dec 8, 2013

You should be using ::x in order to access global variable in local scope. The operator :: is unary scope resolution operator. So your code should be:

   #include <iostream>
   using namespace std;
   int x = 5;
   int main()
   {
       int x = 1;
       cout << "The variable x: " << ::x << endl;
   }   

Note: :: operator has two meanings in C++:

  1. Binary scope resolution operator.
  2. Unary Scope resolution operator.

Almost for your entire coding hours, you would be using the Binary scope resolution operator. So although the answer to this question is unary scope resolution operator; just for the sake of future reference, I enlist some typical use cases of the Binary scope resolution operator.

Use cases of the Binary scope resolution operator:

1. To define your functions outside the class.

We organize our code into header files with .h extension and code files with .cpp extension. While defining our functions in the code files, we use the :: Binary scope resolution operator.

For example,a Car.h file looks like:

class Car
{
    private:
        int model;
        int price;

    public:
        void drive();
        void accelerate();
};

And Car.cpp would look like:

void Car :: drive()
{
    // Driving logic.
}
void Car :: accelerate()
{
    // Logic for accelerating.
}

Here, as we can easily notice, :: acts on two operands:

  1. The class name
  2. The function name

Hence, it essentially defines the scope of the function i.e. it informs the compiler that the function drive() belongs to the class Car.


2. To resolve ambiguity between two functions with same template which are derived from different classes.

Consider the following code:

#include <iostream>
using namespace std;
class Vehicle
{
    public:
    void drive()
    {
        cout << "I am driving a Vehicle.\n";
    }
};
class Car
{
    public:
    void drive()
    {
        cout << "I am driving a Car.\n";
    }
};
class BMW : public Car, public Vehicle
{
    // BMW specific functions.
};
int main(int arc, char **argv)
{
    BMW b;
    b.drive();  // This will give compile error as the call is ambiguous.
    b.Car::drive();  // Will call Car's drive method.  
    b.Vehicle::drive();  // Will call Vehicle's drive method.
}

As both the derived functions of the class BMW have the same template, the call b.drive will result into a compilation error. Hence, to specify which drive() we want, we use the :: operator.


3. To override the overridden function.

Binary scope resolution operator helps to call the function of the base class which is overridden in a derived class using the derived class's object. See the code below:

#include <iostream>
using namespace std;
class Car
{
    public:
    void drive()
    {
        cout << "I am driving Car.\n";
    }
};
class BMW : public Car
{
    public:
    void drive()
    {
        cout << "I am driving BMW\n";
    }
};
int main(int argc, char** argv)
{
    BMW b;
    b.drive(); // Will call BMW's drive function.
    b.Car::drive(); // Will call Car's drive function.
}

4. To access static data members.

As we know, static data members are shared per class basis by the objects of that class. Hence, we should not (although we can) use objects to scope the static variables. See the following code:

#include <iostream>
using namespace std;
class Car
{
    public:
    static int car_variable;
};
int Car :: car_variable;
int main(int argc, char** argv)
{
    Car :: car_variable = 10;
    cout << "Car variable: " << Car :: car_variable << '\n';
    return 0;
}