## Chapter 20: Name Scope Management

## Chapter Goals

- To understand how the management of names is tied to the management of values
- To understand the concepts of scope and visibility, and the various scopes found in C++ programs
- To learn how to use protected visibility to create an interface for derived classes that is different from the public interface
- To understand the use of alternative techniques for the management of names, such as friends, nested classes, and private inheritance
- To learn how to avoid ambiguity and duplicate names by using independent name spaces

## 20.1 Encapsulation

- Control complexity arising from name collisions
- Hide or restrict access to members (sect. 6.3):

  >     class Product
  >     {
  >     public:
  >        Product();
  >        void read();
  >        bool is_better_than(Product b) const;
  >        void print() const;
  >     private:
  >        string name;
  >        double price;
  >        int score;
  >     };

## 20.1 Encapsulation (cont.)

- Encapsulation restricts access to names
- Same as restricting access to values
- E.g., P1 creates a stack class that P2 will use (prev. chapter):
  - Encapsulation limits the information P2 must know
  - Data fields are inaccessible to P2

## 20.2 Name Scopes

Scope
  The part of a program where a name is visible and has meaning (sect. 5.9)

Scopes we have seen:

Block Scope
  Any block delimited by curly braces (`{}`). Name is destroyed after the closing curly brace
Local Scope
  Special case of block scope. A function's local variables and formal parameters have meaning only inside that function

## 20.2 Name Scopes (cont.)

Scopes we have seen (cont.):

Class Scope
  `private` members of a class only have meaning to other members (and friends) of that class
Global Scope
  Identifiers declared outside functions and classes
  From declaration until the end of file
  Visible in other files by declaring it as `extern`
File Scope
  A `static` global - "local" to file

## 20.2 Name Scopes (cont.)

Scopes may nest

>     int count = 0; // Create a global variable
>     . . .
>     int count_items()
>     {
>        int orig_count = count; // holds value in global variable
>        int count = 0; // A different variable named count
>        for (...)
>           count++; // Increment the local variable
>        return count + orig_count;
>     }
>     // Local count and orig_count are no longer available,

## 20.2.1 Shadows and Qualification

- A name can hide (or block) a name from an outer scope
- This name shadows the previous definition
- Name resumes its previous meaning when inner scope exits

## 20.2.1 Shadows and Qualification

To access (some) hidden names:

- Use `this` to get to hidden attributes (next slide)
- Use the unary scope `::` to access globals (next slide)
- Binary scope to get to another class' hidden names:

  >     int TravelClock::get_hours() const
  >     {
  >        int h = Clock::get_hours();
  >           // Qualify which get_hours is intended
  >        . . .
  >     }

## 20.2.1 Example

Perverse example:

>     // DONT WRITE CODE SUCH AS THIS!
>     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
>     };

## 20.2.1 Example (cont.)

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

- `balance` member shadows the global
- C'tor's parameter shadows both the attribute and the global
- Don't need `orig_count`

## Advanced Topic 20.1

Overriding, Shadowing, and Scopes

- Overloading an inherited member function hides that function:

>     class Employee
>     {  . . .
>        virtual void set_salary(int new_salary);
>     };
>     class Manager : public Employee
>     {  . . .
>        virtual void set_salary(int new_salary, int yearly_bonus);
>     };
>     Manager m;
>     m.set_salary(45000); // Error - requires 2 args

## Advanced Topic 20.1 (cont.)

- To fix:
  - Override the function in the derived class
  - call the base class' method explicitly

>     class Manager : public Employee
>     {
>        . . .
>        virtual void set_salary(int new_salary);
>        void set_salary(int new_salary, int yearly_bonus);
>     };

>     void Manager::set_salary(int new_salary)
>     {
>        Employee::set_salary(new_salary); // Invoke the base class function
>     }

## 20.3 Protected Scope

- Derived class inherits `private` members, but can not access them
- `protected` indicates members that only derived classes can access
- Example: `Chart` stores data, derived classes `PieChart`, `BarChart`, etc. each display data in a different fashion:

## 20.3 Protected Scope (cont.)

>     class Chart
>     {
>     public:
>        virtual void draw() const;
>        . . .
>     protected:
>        vector data;
>     };

>     class PieChart : public Chart
>     {
>     public:
>        virtual void draw() const;
>        . . .
>     };

## 20.3 Protected Scope (cont.)

Syntax 20.1: Protected Members
    class ClassName
    {
    	. . .
    protected:
    	member functions and data fields
    };
Purpose: | Declare member functions and data fields that are visible to derived classes.

## 20.3 Protected Scope (cont.)

Syntax 20.1 (cont.)
Example: |
    class Chart
    {
    	. . .
    protected:
    	vector<double> data;
    	double value_at(int index) const;
    };

- Classes now have three interfaces
- Tip: Use protected methods to access private data

## 20.4 Friends

- Grants access to non-public members to another function or non-derived class
- Declare other entity as a friend in class definition
- Each friend must be explicitly named
- Granting friendship to a class grants access to all of its member functions
- Still dangerous, but more precise mechanism

## 20.4 Friends (cont.)

- Refer to section 16.2.1:

  >     class Node
  >     {
  >     public:
  >        Node(string s);
  >     private:
  >        string data;
  >        Node* previous;
  >        Node* next;
  >     friend class List;
  >     friend class Iterator;
  >     };

## 20.4 Friends (cont.)

- Only `List` and `Iterator` are allowed to view and modify data fields of `Node`

- Friendship is granted, not taken
- Friend functions are not member functions
- Access modifier is irrelevant
- Friendship is not symmetric

## 20.4 Friend - syntax

Syntax 20.2: Friends
    class ClassName
    {
    	. . .
    	friend class ClassName;
    	friend return_type function_name(parameter list);
    }
Purpose: | Allow other classes and functions access to private features of a class.

## 20.4 Friend - syntax (cont.)

Example: |
    class Node
    {
    public:
       Node(string s);
    private:
       string data;
       Node* previous;
       Node* next;
    friend class List;
    friend class Iterator;
    };
    class Employee
    {
       . . .
       friend ostream& operator<<(ostream& out,
          const Employee& e)
    };

## 20.4 Friends & Streams

Example: `stream` operators:

>     class Employee
>     {
>     public:
>        Employee(string employee_name, double initial_salary);
>        . . .
>     private:
>        string name;
>        double salary;
>        friend ostream& operator<<(ostream& out, const Employee& e);
>     };

## 20.4 Friends & Streams (cont.)

>     ostream& operator<<(ostream& out, const Employee& e)
>     {
>        out << "Employee: " << e.name;
>        return out;
>     }

## 20.5 Nested Classes

- Compare our `Iterator` (chptr. 16):

  > `Iterator pos = staff.begin();`

- to the STL `iterator`:

  > `list<string>::iterator pos = staff.begin();`

- `iterator` is nested inside the `list` class
- Allows other containers to define their own iterators with different behaviors

## 20.5 Nested Classes (cont.)

- Have the same interfaces
- Share names, but not in the same namespace
- Expressed with a qualified name:

  > `vector<double>::iterator p = a.begin();
  > list<string>::iterator q = b.begin();`

## 20.5 Nested Classes - syntax

Syntax 20.3: Nested Class Declaration
    class OuterClassName
    {
       . . .
       class NestedClassName;
       . . .
    };

## 20.5 Nested Classes - syntax (cont.)

Syntax 20.3: Nested Class Declaration (cont.)
Example: |
    class List
    {
       . . .
       class Iterator;
    };
Purpose: | Declare a class whose scope is contained in the scope of another class

## 20.5 Nested Classes (cont.)

To nest `Iterator` (chptr. 16) inside `List`:

- Will be used as:

  > `List::Iterator pos = staff.begin();`

- Declare the nested class w/a forward reference in outer class:

  >     class List
  >     {
  >        . . .
  >        class Iterator;   // Forward reference
  >        . . .
  >     };

## 20.5 Nested Classes (cont.)

- Define class and its methods, always referring to its full name:

  >     class List::Iterator
  >     {
  >     public:
  >        Iterator();
  >        string get() const;
  >        . . .
  >     };

  >     List::Iterator::Iterator()
  >     { . . . }

  >     string List::Iterator::get() const
  >     { . . . }

## 20.5 Nested Classes (cont.)

Or, include the entire definition inside the outer class:

>     class List
>     {
>        . . .
>        class Iterator
>        {
>        public:
>           Iterator();
>           string get() const;
>           . . .
>        };
>        . . .
>     };

## 20.5 Nested Classes (cont.)

- Does not imply that a `List` object contains an `Iterator` object
- The name `Iterator` is in the scope of the `List` class
- `List` member functions can refer to it simply as `Iterator`
- All other functions refer to it as `List::Iterator`
- Nested classes need not be public
- Declaring nested class as `private` encapsulates entire definition
  - May only be created by members of outer class

## 20.5 `private` Nested Class - Example

From chptr. 18:

- `StringReference` is private to `SharedString`
- Though all attributes are public, they are local to `SharedString`

## 20.5 `private` Nested Class - Example (cont.)

>     class SharedString
>     {
>        . . .
>     private:
>        class StringReference;
>        . . .
>     };

>     class SharedString::StringReference
>     {
>     public:
>        int count;
>        char* buffer;
>        StringReference(const char* right);
>        ~StringReference();
>     };

## Quality Tip 20.4

Manage Encapsulation

- Tools to manage encapsulation:

- class definitions
- access modifiers
- nested classes
- namespaces

- There are often several ways to address a problem
- Consider the results of the various methods
- Plan carefully

## 20.6 Private Inheritance and Names

- Inheritance normally implies an "is-a" relationship
  - Substitution principle: If `B` inherits from `A`, then `B` can be used wherever `A` is expected
  - Interface for the base class becomes a basis for the i/f for the derived class
- We occasionally use inheritance even when the "is-a" relationship doesn't hold (see example)
  - A solution is to declare that `Set` inherits privately from `List`
  - With private inheritance all inherited attributes become private in the derived class
  - The base class' interface does not flow through to the derived class

## 20.6 Private Inheritance and Names - syntax

Syntax 20.4: Private Inheritance
    class DerivedClassName : private BaseClassName
    {
       features;
    }
Purpose: | To allow the derived class access to the functionality of the base class, without declaring the derived class as a specialized form of the base class.

## 20.6 Private Inheritance and Names - syntax (cont.)

Syntax 20.4: Private Inheritance (cont.)
Example: |
    class Set : private List
    {
    public:
       void add(string s);
       Iterator erase(Iterator pos);
       Iterator begin();
       Iterator end();
    };

## 20.6 Private Inheritance - example

- Inherit from `List` to implement `Set`
- But many of the `List` methods would be inappropriate for a `Set`

>     class Set : private List
>     {
>     public:
>        void add(string s);
>        Iterator erase(Iterator pos);
>        Iterator begin();
>        Iterator end();
>     };

## 20.6 Private Inheritance - example (cont.)

>     void Set::add(string s)
>     {
>        Iterator iter = begin();
>        Iterator stop = end();
>        while (iter != stop)
>        {
>           if (s.equals(iter.get()))
>              return; // Already in set, dont add
>        }
>        push_back(s); // Can use inherited push_back method
>     }

## 20.6 Private Inheritance - example (cont.)

>     Iterator Set::erase(Iterator pos)
>     {
>        List::erase(pos);
>     }

>     Iterator Set::begin()
>     {
>        return List::begin();
>     }

>     Iterator Set::end()
>     {
>        return List::end();
>     }

## 20.6 Private Inheritance - example (cont.)

- `Set` method may call `push_back`
- `push_back` is not part of `Set`'s interface:

  > `Set a_set;
  > a_set.add("Sally"); // legal
  > a_set.push_back("Fred");
  > // Error--push_back not part of interface for Set`

- Private inheritance is rarely used
- `Set` could've instead had a private `List` attribute (aggregation)
- Similarly, protected inheritance exists, but is used even less often

## 20.7 Name Spaces

- Mechanism to avoid naming conflicts:
  - Consider a programmer who creates a `map` class, e.g., for a computer game
  - There is already a `map` class in the STL
  - But, all the STL classes are in the `std` namespace
  - Can reference `std::map` explicitly
  - Could alternatively (or additionally) put the other `map` class in another namespace

## 20.7 Name Spaces - syntax

Syntax 20.5: Name Space Definition
    namespace name_space_name
    {
       feature1
       feature2
       . . .
       featuren
    }

## 20.7 Name Spaces - syntax (cont.)

Syntax 20.5: Name Space Definition (cont.)
Example: |
    namespace ACME_Software_San_Jose_CA_US
    {
       class map
       {
          . . .
       };
    }
Purpose: | Include a class, function, or variable in a name space.

## 20.7 Name Spaces (cont.)

- Wrap declarations in a `namespace` block to add names to a namespace:

  >     namespace acme
  >     {
  >        class map
  >        {
  >           . . .
  >        };

  >        void draw(map m);
  >     }

## 20.7 Name Spaces (cont.)

- Name spaces are open; add items by creating another block w/the same name:

  >     namespace acme
  >     {
  >        class maze
  >        {
  >           . . .
  >        };
  >     }

- Use unambiguous (long) names for namespaces

## 20.7 Name Spaces - the `using` directive

- Dumps entire namespace (or selected names) into global namespace
- Avoids using fully qualified names
- Beware of conflicts
- To add entire namespace:

  > `using namespace std;`

- To pick which names to add:

  > `using std::cout; // Include only cout from the std namespace`

- Do not put `using` statements in header (included) files

## 20.7 Name Spaces Alias

- Use a short alias for a long namespace name:

Syntax 20.6: Name Space Alias
    namespace alias_name = name_space_name;
Example: |
    namespace acme = ACME_Software_San_Jose_CA_US;
Purpose: | Introduce a short alias for the long name of a name space

- You can use different alias names for the same namespace in different files

## 20.8 Case Study: Matrices, Continued

- `MatrixRow` and `ConstMatrixRow` are nested in `Matrix`
  - Renamed to `Row` and `constRow`
  - Declared as `private`, since they won't be created outside of `Matrix`
  - Replaced references to MatrixRow with `Matrix::Row`
- Nested `MatrixIndexException` and `MatrixMismatchException` inside `Matrix`
- Wrapped all classes in the `BigCPlusPlus_Matrix` namespace
  - No `using` statements in header file
  - Test file aliases and imports all of `BigCPlusPlus_Matrix`, and `std::cout`

## 20.8 Case Study: Matrices (`matrix4.h`)

## 20.8 Case Study: Matrices (`matrix4.cpp`)

## 20.8 Case Study: Matrices (`matrixtest4.cpp`)

## Chapter Summary

1. Encapsulation helps reduce the number of visible names
2. Scope refers to the portions of a program where a name is visible
3. A variable that hides another variable of the same name in a different scope is said to shadow the hidden name
4. `protected` members are accessible to derived classes
5. A friend is a function or another class that is granted access to all features of a class
6. A nested class is defined inside another class to limit the nested class' names to the outer class' scope