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:
- First, declare the nested class with a forward reference inside the outer class
- 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 {
};
}