170 likes | 305 Views
C++ Certificate Program C++ Intermediate. Access Control. What is Access Control?. Three tenets of O-O programming: Encapsulation Inheritance Polymorphism (typically runtime / dynamic binding) Access control concerned with encapsulation What do we want visible? What do we want to hide?
E N D
C++ Certificate ProgramC++ Intermediate Access Control
What is Access Control? • Three tenets of O-O programming: • Encapsulation • Inheritance • Polymorphism (typically runtime / dynamic binding) • Access control concerned with encapsulation • What do we want visible? • What do we want to hide? • From whom?
C++ Access Control • C++ supports three levels of access control • Public : visible to all • Protected: visible to derived classes • Private: visible only to the class
Access Control Uses • Intended to support design policy • Aids in the communication of a design by delineating what is intended to be visible • Can be used to promote loose-coupling (hard to couple to what you cannot see) • C++ access control is not a runtime security mechanism, but a compile-time design enforcement mechanism
Sibling Access class Car { protected: double getMilesPerGallon () const { /* … */ } // … }; namespace Honda { class Civic : public Car { public: double getResaleValue () const { double mpg = getMilesPerGallon (); // ok // … } bool shouldTradeFor (Car const& car) { double newMPG = car.getMilesPerGallon (); // ILLEGAL! // … } }; }
Sibling Access • Why is this illegal? • Protected and private methods can be accessed between different objects of the same class • Base class protected method can be called from within derived object method • However, siblings should not have access to the other’s private (or protected) methods; for example, Civic should not be able to call getMilesPerGallon on a Saab object
Explanation from ARM • The C++ Annotated Reference Manual (ARM) explains this further: • When a friend or a member function of a derived class references a protected nonstatic member of a base class, an access check applies in addition to those described earlier. . . Except when forming a pointer to member, the access must be through a pointer to, reference to, or object of the derived class itself (or any class derived from that class). . .
Friend Declarations • A class, global function, or method may be declared to be a friend of a class • Friend has unrestricted access to private and protected members of the class • Friend declarations are not inherited or transitive - a friend of a friend does not automatically become a friend, a friend of a parent does not automatically become a friend
Example Friend Declarations class Employee {// friend functions and classes are // given unrestricted access to all // public, private and protected // attributes and methods friend class Secretary; friend void ::IRS_Audit(); friend void Boss::Spy();};
More on Friends • You can specify who your friends are • You cannot limit what friends have access to • Friends can access everything an instance of your class can • Often, but not always, use of friends is indicative of a weak design
Template Friends • Friends can be declared in template classes, to generate many friends: template <typename T> class Bar { }; template <typename T> class Foo { // ... friend class Bar<T>; };
Iterators • Iterator classes provide ideal example where friend relationships can actually produce better design • Iterators require intimate knowledge of the container class it is iterating against • A container typically needs one outside class (usually under control of the container designer) with intimate knowledge of the container implementation details; outside users need only know container interface details
Std Lib List Container • In the example of std::list, every user of the class accesses the list through its non data-revealing / non implementation-revealing public interface • Iterator is needed to access any elements
Iterator Design Drivers Why are the iterator classes separate, nested classes rather than just exposing data within the list's interface? • Is one iterator enough? Will there be multiple clients to the container? • Multiple iterators are needed • Will standard algorithms be used on the container? • Iterators allow generic algorithms that work with any container • Algorithm code is insulated from binding to members of any specific container
Iterator Design Drivers • Will there ever be a need to change the underlying container? • Iterators reduce reliance on a specific class interface • Underlying container can be changed and the application code is unaffected
Iterators Are Your Friends • All of the above pushes for the use of iterators • “a window into a container” • Client code still has control over the container, regardless of what really goes on behind the scenes • Iterators are an excellent example of selective exposure • Clients get what they need and only what they need • Many functions only need to access container iterators, not the container itself • Decouples client code from the implementation of the containers
Summary • C++ access control and friends are all aspects of the public interface • Public interface defines what a type can do, to the users of that type • Separating the interface from the implementation is crucial to good software design • The responsibilities / functionality / interface of a type (class) lies at the heart of O-O programming