C++ Class Construct  «Prev  Next»
Lesson 3 The scope resolution operator
ObjectiveUnary form of the scope resolution operator.

Unary Form of the Scope Resolution Operator in C++

The unary form of the scope resolution operator (`::`) in C++ is used to access global namespace identifiers, including variables and functions, from within another scope where a local identifier might shadow a global identifier.
  • Description In C++, the scope resolution operator `::` helps specify which namespace or class scope to search to resolve an identifier. When used in its unary form (without a preceding class or namespace name), it explicitly denotes the global namespace. This is particularly useful when local variables or identifiers within a block, function, or namespace might overshadow global variables with the same name.
  • Usage: Using the unary scope resolution operator ensures that the program refers to a global variable or function rather than a similarly named local one. It is a way to disambiguate the reference, making clear the programmer's intent to use the global version.

Example: Consider a scenario where you have a global variable and a local variable in the same function with the same name. Here's how you might use the unary scope resolution operator to distinguish between them:
#include <iostream>

int number = 42;  // Global variable

void function() {
   int number = 24;  // Local variable shadowing the global variable

   // Prints the local 'number'
   std::cout << "Local number: " << number << std::endl;

   // Prints the global 'number' using the unary scope resolution operator
   std::cout << "Global number: " << ::number << std::endl;
}

int main() {
   function();
   return 0;
}

Output
Local number: 24
Global number: 42

Explanation
In the function `function()`, there are two variables named `number`: one local to the function and one defined in the global scope. The local `number` shadows the global `number` within the function. To access the global `number` and differentiate it from the local one, the unary scope resolution operator `::` is used before `number` (`::number`), indicating that the compiler should look in the global scope for the variable. This feature is particularly useful in larger projects with many functions and potentially overlapping variable names, helping maintain clarity and prevent unintended behavior due to variable shadowing.

C++ Classes

Used to access a Variable or Object

The scope resolution operator's unary form is used to access a variable or object that is at external scope and that has been "hidden" by an identically named variable or object declared at local or class scope.
int count = 0;        //external variable
void how_many(double w[], double x, int& count){
 for (int i = 0; i < N; ++i)
  count += (w[i] == x);
 ++ ::count;         //keep track of calls
}

A namespace is a sort of family name that prefixes all the names declared within the namespace. The names in the standard library are all defined within a namespace that has the name std. cout and endl are names from the standard library so the full names are std::cout and std::endl. Those two colons together, ::, have a very fancy title: the scope resolution operator. I’ll have more to say about it later. Here, it serves to separate the namespace name, std, from the names in the Standard Library such as cout and endl. Almost all names from the Standard Library are prefixed with std.
The code for a namespace looks like this:
namespace ih_space {
// All names declared in here need to be prefixed
// with ih_space when they are reference from outside.
// For example, a min() function defined in here
// would be referred to outside this namespace as ih_space::min()
}

Everything between the braces is within the ih_space namespace.
Warning: The main() function must not be defined within a namespace. Things that are not defined in a namespace exist in the global namespace, which has no name.
Example of Unary Scope Resolution Operator
#include <iostream>
using namespace std;
int n = 5; 

int main(){
  double n = 11.7;
  cout << "Local double value of n = " << n
    << "\nGlobal int value of n = " << ::n << endl;
  return 0;
}

Local double value of n = 11.7
Global int value of n = 5


Defining Methods

The preceding definition for the SpreadsheetCell class is enough for you to create objects of the class.
However, if you try to call the setValue() or getValue() methods, your linker will complain that those methods are not defined. That is because the class definition specifies the prototypes for the methods, but does not define their implementations. Just as you write both a prototype and a definition for a stand-alone function, you must write a prototype and a definition for a method. Note that the class definition must precede the method definitions. Usually the class definition goes in a header file, and the method definitions go in a source file that includes that header. Here are the definitions for the two methods of the SpreadsheetCell class:
#include "SpreadsheetCell.h"
void SpreadsheetCell::setValue(double inValue){
 mValue = inValue;
}
double SpreadsheetCell::getValue() const{
 return mValue;
}

Note that the name of the class followed by two colons precedes each method name:
void SpreadsheetCell::setValue(double inValue)

The :: is called the scope resolution operator. In this context, the syntax tells the compiler that the coming definition of the setValue() method is part of the SpreadsheetCell class. Note also that you do not repeat the access specification when you define the method.

SEMrush Software