C++ Scopes, Name spaces and Nested Classes
June 11, 2020 by Jane

Local scope - function scope

Block scope - scope defined by a set of curly braces

Class scope - scope defined by class definition

Global scope - variables declared outside of function and class definitions

File scope - global static variables have file scope, non-static variables maybe shared across many files with the use of "extern" but static variables are only seen in the file they're declared in.

Protected scope - scope defined by the "protected" accessor modifier, seen by the base class itself and derived classes only.

 

E.g. Examples of local, global, class scope variables

double balance; // balance has global scope
class BankAccount {
public:
    BankAccount(double balance);
// Parameter variable balance has local scope
private:
    double balance;
// Data field balance has class scope

};
BankAccount::BankAccount(double balance) {
    this->balance = balance;
// Assign data field balance using parameter value
    ::balance = balance; // Assign global variable using parameter value
}

 

Shadowing:

  • Shadowing in programming means that a variable with the same name as another may shadow the other variable if its scope is more relevant.
  • In the above example, inside the constructor the balance with local scope shadows the global and class scope variables:
    • To refer to the class scope balance we had to use this->balance
    • To refer to the global scope balance variable we had to use the global qualifier ::balance.

 

Keyword "using":

  • The "using" keyword in C++ is used to shorten programmer's typing, it is also used to change the relevancy of various classes and methods so that they shadow the others
  • The most common example is "using namespace std;"  this expression allows the programmer to use methods from the standard library without having to type "std::" before every "cout"
  • Another example is if we wanted to use the stack implementation we wrote instead of the standard library's we could write "using my_name_space::stack; where my_name_space is a namespace we defined.

E.g.

using namespace std; // stack now refers to the stack defined in namespace std

void calc(int a) {

    using insonium::stack; // stack now refers to the stack defined in namespace "insonium"

}

// stack now refers to the stack defined in namespace std because the function scope ended

 

Namespace scope - scope defined by nesting classes

  • Namespace scope is created by placing the name of a class inside the scope of another class.
  • Nested classes need not be in the public portion of a class definition. Declaring a nested class as private encapsulates the entire class definition
    • Instances of the nested class can only be manipulated by functions that are permitted to access private members of the outer class
    • There is no danger in making the data members of the nested class public since the class itself a private nested class
  • A nested class has no right to access private members of the outer class (unless it has been declared as a friend), and the outer class has no right to access private members of the inner class
  • The outer class can refer to the nested class by its class name while all the other classes must refer to the nested class with fully qualified name outer_class_name::nested_class_name
  • To nest a class inside another involves two steps:
  1. First, declare the nested class with a forward reference inside the outer class
  2. Then define the class and its member functions, always referring to the class by its
    full name (such as List::Iterator).

E.g.
class List {
    class Iterator;
// Forward reference
};

// define the class and its member functions, always referring to the class by its
full name

class List::Iterator {
public:
    Iterator();
    string get() const;
};
List::Iterator::Iterator() {//implementation
}

string List::Iterator::get() const {//implementation}
 

E.g. 2. Nested syntax. It's also possible to do this however depending on the coding convention of the programmers, it may be discouraged as it can appear confusing
class List{
    ...
    class Iterator
    {
    public:
        Iterator();
        string get() const;
        ...
    };
    ...
};

 

Name spaces:

  • A mechanism used to avoid naming conflicts
  • A name space may include classes, functions, variables
  • To add entities to a name space, surround the declaration with a namespace block
  • Sometimes namespaces are very long because they are made to be very specific to avoid naming conflicts. It's possible create an alias with namespace alias_name = name_space_name
    •  E.g. namespace acem = ACEM_Company_Engine_X
  • Namespace declarations can be spread out, one can add as many items to a name space as one would like, by starting another namespace block and wrapping the entities inside

E.g.

namespace Test {

    class Harness {

    };

}

... // some other code

namespace Test {

    class Setup {

    };

}