Presentation is loading. Please wait.

Presentation is loading. Please wait.

Lecture 13.

Similar presentations


Presentation on theme: "Lecture 13."— Presentation transcript:

1 Lecture 13

2 Recap Separation of Interface and Implementation
Objects are Declared as Primitive Type The Destructor Operator Copy Constructor Default Constructor

3 Selective Questions from Exercise

4 Q: What is information hiding. What is encapsulation
Q: What is information hiding? What is encapsulation? How does C++ support these concepts? Answer: Information hiding makes implementation details, including components of an object, inaccessible. Encapsulation is the grouping of data and the operations that apply to them to form an aggregate while hiding the implementation of the aggregate. Encapsulation and information hiding are achieved in C++ through the use of the class.

5 Q: Explain the public and private sections of the class.
Answer: Members in the public section of a class are visible to non-class routines and can be accessed via the. member operator. Private members are not visible outside of the class.

6 Q: Describe the roles of the constructor and destructor.
Answer: The constructor is called when an object is created, either by declaration, a call to new, or as a member of an object which itself is being constructed. The destructor is called when the object exits scope, either because it is a local variable in a terminating function, it is subject to a delete, or it is a member of an object whose destructor is called.

7 Q: What is the difference between a copy constructor and a copy assignment operator?
Answer: The copy constructor creates and initializes a new object. It is used to implement call by value. The copy assignment operator copies into an already existing object.

8 Q: If a class provides no constructor and no destructor, what is the result?
Answer: The default constructor is a member-by-member application of a default constructor. The default destructor is a member-by-member application of a destructor.

9 Chapter 4 Inheritance

10 Introduction In this chapter we will study
how the general principles of inheritance and the object-oriented concept of polymorphism relate to code reuse, how inheritance is implemented in C++, how a collection of classes can be derived from a single abstract class, how run-time binding decisions, rather than compile-time linking decisions, can be made for these classes.

11 Introduction to Inheritance
On one level inheritance is the fundamental object-oriented principle governing the reuse of code among related classes Inheritance models the IS-A relationship In an IS-A relationship, the derived class is a base class For example: a Circle IS-A Shape and a Car IS-A Vehicle. However, an Ellipse IS-NOT-A Circle Inheritance relationships form hierarchies For instance: we can extend Car to other classes, as a Foreign car IS-A Car and a Domestic car IS-A Car and so on

12 Continued…. Another type of relationship is a HAS-A relationship
In a HAS-A relationship, the derived class has a base class. This type of relationship does not possess the properties that would be natural in an inheritance hierarchy For Example: A car HAS-A steering wheel Generally, HAS-A relationships should not be modeled by inheritance. Instead, they should be modeled with the technique of composition, in which the components are simply made private data fields

13 Inheritance in C++ Exceptions Files
The C++ language itself makes some use of inheritance in implementing its class libraries. Two examples are Exceptions Files

14 Exceptions C++ defines in <stdexcept> the class exception
There are several kinds of exceptions, including bad_alloc and bad_cast In figure Classes in exception hierarchy has been shown Each is a separate class, but for all of them, the what method can be used to return a string that details an error message

15 I/O Operation In figure
streams hierarchy uses inheritance In actual, the streams hierarchy is more complex than shown

16 IS-A Relationship The inheritance models an IS-A relationship
A button IS-A component A bad_cast IS-A exception An if stream IS-A istream Because of IS-A relationships, the fundamental property of inheritance guarantees that any method that can be performed by istreamcan also be performed by ifstreamand that an ifstream object can always be referenced by an istream reference The reverse is not true This is why I/O operations are typically written in terms of istream and ostream.

17 Continued…. what is a method available in the exception class
If we need to catch various exceptions we can use a catch handler and write: { catch( const exception & e ) I cout << e.what( ) << endl; } If e references a bad_cast object, the call to e .what ( ) makes sense The reason is that an exception object supports the what method, and a bad-cast IS-A exception, meaning that it supports at least as much as exception Depending on the circumstances of the class hierarchy, the what method could be invariant or it could be specialized for each different class When a method is invariant over a hierarchy-that is, it always has the same functionality for all classes in the hierarchy-we avoid having to rewrite an implementation of a class method

18 Polymorphism in Inheritance
The call to what illustrates an important object-oriented principle known as polymorphism It is the ability of a reference variable to reference objects of several different types When operations are applied to the variable, the operation that is appropriate to the actual referenced object is automatically selected The same is true for pointer variables In the case of an exception reference, a run time decision is made Like: The what method for the object that e actually references at run time is the one used. This action is known as dynamic, or late, binding Unfortunately, although dynamic binding is the preferred behavior, it is not the default in C++. This language flaw leads to complications

19 Classes in Inheritance
Inheritance is the process of deriving a class from a base class without disturbing the implementation of the base class The base class is the foundation for inheritance A derived class is a completely new class that inherits all the properties of the base class, with all the public methods available to the base class becoming public methods with identical implementation of the derived class The derived class can then add data members and additional methods and change the meaning of the inherited methods The base class is completely unaffected by any changes that are made in the derived class In designing the derived class, breaking the base class is impossible, which greatly simplifies the task of software maintenance

20 Continued…. A derived class is type compatible with its base class
A reference variable of the base class type may reference an object of the derived class, but not vice versa Sibling classes (i.e., classes derived from a common class) are not type compatible The exception hierarchy highlights the typical design approach of factoring commonalities into base classes and then specializing in the derived classes In this hierarchy, we say that the derived class is a subclass of the base class and the base class is a superclass of the derived class These relationships are transitive

21 Continued…. The arrows in the hierarchy diagrams reflect the modern convention of pointing toward the top (or root) of the hierarchy The stream hierarchy illustrates some fancier design decisions Among other things, commonality among istream and ostream is factored out and placed in ios iostream inherits from both istream and ostream, illustrating multiple inheritance

22 Inheritance Basics Derived class inherits all the properties of a base class It can add data members, disable functions, alter functions, and add new functions, becoming a completely new class The form of inheritance used mostly is public inheritance Public Inheritance is the process by which all public members of the base class remain public in the derived class Private inheritance is the process occasionally used to implement a HAS-A relationship In private inheritance even public members of the base class remain hidden A public inheritance is used to models an IS-A relationship

23 General Layout of Public Class
1 class Derived : public Base 2 { 3 // Any members that are not listed are inherited unchanged 4 // except for constructor, destructor, 5 // copy constructor, and operator= 6 public: 7 // Constructors, and destructors if defaults are not good 8 // Base members whose definitions are to change in Derived 9 // Additional public member functions 10 private: 11 // Additional data members (generally private) 12 // Additional private member functions 13 // Base members that should be disabled in Derived 14 };

24 Derived Class Generally all data are private, so we just add additional data members in the derived class by specifying them in the private section Any base class member function that is declared in the derived class private section is disabled in the derived class Any base class member function declared in the derived class's public section requires an overriding definition that will be applied to objects of the derived class Additional member functions can be added in the derived class

25 Visibility Rules Any member declared with private visibility is accessible only to methods of the class Thus any private member in the base class are not accessible to the derived class We want the derived class to have access to the base class members There are several options One is to use public access. However, it allows access to other classes in addition to derived classes Another is to use a friend declaration, but this approach is also poor design and would require friend declaration for each derived class

26 Continued…. If we want to allow access only to derived classes, we can make members protected A protected class member is private to every class except a derived class However, declaring data members as protected or public violates the spirit of encapsulation and information hiding and is generally done only as a matter of programming expediency A better alternative usually is to write accessor and mutator methods If a protected declaration allows you to avoid convoluted code, then using it is not unreasonable Protected data allows a derived class to inherit an internal method without making it accessible outside the class hierarchy

27 The Constructor and Base Class Initialization
Constructors should be defined for each derived class If no constructor is written, a single zero-parameter default constructor is generated This constructor will call the base class zero-parameter constructor for the inherited portion Then apply the default initialization for any additional data members Constructing a derived class object by first constructing its inherited portion is standard practice It is done by default even if an explicit derived class constructor is given. This action is natural because encapsulation means that the inherited portion is a single entity, and the base class constructor tells us how to initialize this single entity

28 Continued…. Base class constructors can be explicitly called by name in the initializer list Thus the default constructor for a derived class, in reality, is Derived ( ) : Base { } { } The base class initializer can be called with parameters that match a base class constructor

29 Example The following example illustrates the UnderflowException class that could be used in implementing data structures 1 class UnderflowException : public underflow-error 2 { 3 public: 4 UnderflowException( const string & msg = "" ) 5 : underflow-error( msg.c-str( ) ) { } 6 };

30 Explanation of Example
The UnderflowException is thrown when an attempt is made to extract something from an empty data structure An UnderflowException object is constructed by providing an optional string The underflow_error class specification requires a primitive string, so we need to use an initializer list As the UnderflowException object adds no data members, the construction method is simply to use the underf low_error constructor to construct the inherited portion

31 Adding Members A derived class inherits from its base class the behavior of the base class All methods defined for the base class are now defined for the derived class Now we examine the consequences of adding extra methods and data members Example in next slide

32 Example (BadIndex class derived from exception class)
1 // Example of a derived class that adds new members. 2 3 class BadIndex : public exception 4 { 5 public: 6 BadIndex( int idx, int sz ) 7 : index( idx ), size( sz ) { } 8 9 int getIndex( ) const 10 { return index; } 11 int getsize( ) const 12 { return size; } 13 14 private: 15 int index; 16 int size; 17 };

33 Explanation of Example
The BadIndex class has one constructor and three methods The constructor accepts two parameters It initializes the inherited exception portion by using a zero-parameter constructor The three methods available for BadIndex are getIndex getSize what The behavior of what is unchanged from the exception class

34 Continued…. Besides the new functionality, BadIndex has two data members in addition to the data members inherited from exception If the inherited data are private, they are inaccessible Our design works regardless of the underlying data representation in exception Changes to the private implementation of exception will not require any changes to BadIndex

35 Example (Using BadIndex class)
1 // Use the BadIndex exception. 2 int main( ) 3 { 4 NewVector<int> v{ 10 }; 5 6 try 7 { 8 for( int i = 0; i <= v.size( ) ; i++ ) // off-by-one 9 v[ i ] = 0; 10 } 11 catch( const BadIndex & e ) 12 { 13 cout << e.what( ) << ", index=" << e.getIndex( ) 14 << “ , size=" << e.getSize( ) << endl; 15 } 16 17 return 0; 18 }

36 Explanation of Example
If there is a BadIndex exception thrown, it is caught at lines Information can be printed by calling the exception's public member functions As a BadIndex IS-A exception, at line 1 1 we could catch it with an exception reference. One could apply the what method to get some information One could not apply the getIndex and getsize methods because they are not defined for all except ion objects


Download ppt "Lecture 13."

Similar presentations


Ads by Google