6.088-6 Inheritance and polymorphism; templates in C++

Add to Favourites
Post to:

6.088 Intro to C/C++Day 5: Inheritance & PolymorphismEunsuk Kang & JeanYangIn the last lecture... Objects: Characteristics & responsibilities Declaring and defining classes in C++ Fields, methods, constructors, destructors Creating & deleting objects on stack/heap Representation invariant Today’s topicsInheritance Polymorphism Abstract base classes InheritanceTypes A class defines a set of objects, or a typepeople at MITTypes within a type Some objects are distinct from others in some waysMIT professors MIT students people at MITSubtype MIT professor and student are subtypes of MIT peopleMIT professors MIT students people at MITType hierarchy MIT Person Student Professor extends extends What characteristics/behaviors do people at MIT have in common? Type hierarchyMIT Person extends extends Student Professor What characteristics/behaviors do people at MIT have in common? �name, ID, address �change address, display profile Type hierarchy MIT Person Student Professor extends extends What things are special about students? �course number, classes taken, year �add a class taken, change course Type hierarchy MIT Person Student Professor extends extendsWhat things are special about professors? �course number, classes taught, rank (assistant, etc.)�add a class taught, promote Inheritance A subtype inherits characteristics and behaviors of its base type. e.g. Each MIT student has Characteristics: Behaviors: name display profile ID change address address add a class taken course number change course classes taken year Base type: MITPerson#include class MITPerson { protected: int id; std::string name; std::string address; public: MITPerson(int id, std::string name, std::string address); void displayProfile(); void changeAddress(std::string newAddress); }; Base type: MITPersonclass MITPerson { protected: int id; std::string name; std::string address;#include namespace prefix public: MITPerson(int id, std::string name, std::string address); void displayProfile(); void changeAddress(std::string newAddress); }; Base type: MITPerson #include public: MITPerson(int id, std::string name, std::string address); void displayProfile(); void changeAddress(std::string newAddress); }; access control class MITPerson { protected: int id; std::string name; std::string address;Access control Public accessible by anyone Protected accessible inside the class and by all of its subclasses Private accessible only inside the class, NOT including its subclasses Subtype: Student #include #include #include "MITPerson.h" #include "Class.h" class Student : public MITPerson { int course;int year; //1 = freshman, 2 = sophomore, etc.std::vector classesTaken; public: Student(int id, std::string name, std::string address, int course, int year);void displayProfile();void addClassTaken(Class* newClass);void changeCourse(int newCourse); }; Subtype: Student #include #include dynamic array, #include "MITPerson.h" #include "Class.h" part of C++ standard libraryclass Student : public MITPerson { int course; int year; //1 = freshman, 2 = sophomore, etc. std::vector classesTaken; public: Student(int id, std::string name, std::string address, int course, int year);void displayProfile();void addClassTaken(Class* newClass);void changeCourse(int newCourse); }; Subtype: Student #include #include #include "MITPerson.h" #include "Class.h" class Student : public MITPerson { int course;int year; //1 = freshman, 2 = sophomore, etc.std::vector classesTaken; public: Student(int id, std::string name, std::string address, int course, int year);void displayProfile();void addClassTaken(Class* newClass);void changeCourse(int newCourse); }; Constructing an object of subclass #include #include #include "MITPerson.h" #include "Class.h" class Student : public MITPerson { int course;int year; //1 = freshman, 2 = sophomore, etc.std::vector classesTaken; public: Student(int id, std::string name, std::string address, int course, int year); void displayProfile();void addClassTaken(Class* newClass);void changeCourse(int newCourse); }; Constructing an object of subclass //in Student.cc Student::Student(int id, std::string name, std::string address, int course, int year) : MITPerson(id, name, address) { this->course = course; this->year = year; } //in MITPerson.cc MITPerson::MITPerson(int id, std::string name, std::string address){ this->id = id; this->name = name; this->address = address; } Calling constructor of base class call to the base constructor //in Student.cc { this->course = course; this->year = year; } int course, int year) : MITPerson(id, name, address) Student::Student(int id, std::string name, std::string address, //in MITPerson.cc MITPerson::MITPerson(int id, std::string name, std::string address){ this->id = id; this->name = name; this->address = address; } Constructing an object of subclassStudent* james =new Student(971232, “James Lee”, “32 Vassar St.”, 6, 2); name = “James Lee” ID = 971232 person address = “32Vassar St.” course number = 6 classes taken = none yet year = 2 student Overriding a method in base class class MITPerson { protected: int id; std::string name;std::string address;public: MITPerson(int id, std::string name, std::string address); void displayProfile(); void changeAddress(std::string newAddress); }; class Student : public MITPerson { int course; int year; //1 = freshman, 2 = sophomore, etc. std::vector classesTaken; public:Student(int id, std::string name, std::string address, int course, int year);void displayProfile(); //override the method to display course & classes void addClassTaken(Class* newClass);void changeCourse(int newCourse);}; Overriding a method in base classvoid MITPerson::displayProfile() { //definition in MITPerson std::cout << "-----------------------------\n"; std::cout << "Name: " << name << " ID: " << id << " Address: " << address << "\n"; std::cout << "-----------------------------\n"; } void Student::displayProfile(){ //definition in Student std::cout << "-----------------------------\n"; std::cout << "Name: " << name << " ID: " << id << " Address: " << address << "\n"; std::cout << "Course: " << course << "\n"; std::vector::iterator it; std::cout << "Classes taken:\n"; for (it = classesTaken.begin(); it != classesTaken.end(); it++){ Class* c = *it; std::cout << c->getName() << "\n"; } std::cout << "-----------------------------\n";} --------------------------------------------------------------------------------------------------------------------Overriding a method in base classMITPerson* john = new MITPerson(901289, “John Doe”, “500 Massachusetts Ave.”); Student* james = new Student(971232, “James Lee”, “32 Vassar St.”, 6, 2); Class* c1 = new Class(“6.088”); james->addClassTaken(c1); john->displayProfile(); james->displayProfile(); Name: John Doe ID: 901289 Address: 500 Massachusetts Ave. Name: James Lee ID: 971232 Address: 32 Vassar St.Course: 6Classes taken:6.088 PolymorphismPolymorphism Ability of type A to appear as and be used like another type B e.g.A Student object can be used in place of an MITPerson object Actual type vs. declared type Every variable has a declared type at compile-time But during runtime, the variable may refer to an object with an actual type (either the same or a subclass of the declared type) MITPerson* john = new MITPerson(901289, “John Doe”, “500 Massachusetts Ave.”); MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); What are the declare types of john and steve? What about actual types? Calling an overridden functionMITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); steve->displayProfile(); ----------------------------------------------------------Calling an overridden function MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); steve->displayProfile(); Name: Steve ID: 911923 Address: 99 Cambridge St.Why doesn’t it display the course number and classes taken? Virtual functions Declare overridden methods as virtual in the base class MITPerson { protected:int id; std::string name;std::string address;‘virtual’ keyword }; public: MITPerson(int id, std::string name, std::string address); virtual void displayProfile(); virtual void changeAddress(std::string newAddress); What happens in other languages (Java, Python, etc.)?----------------------------------------------------------Calling a virtual function MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); steve->displayProfile(); Name: Steve ID: 911923 Address: 99 Cambridge St. Course: 18 Classes taken: vptr What goes on under the hood?Virtual table �stores pointers to all virtual functions �created per each class �lookup during the function call Student object MITPerson* &Student::displayProfile &MITPerson::changeAddress steve VTABLENote “changeAddress” is declared virtual in but not overridden Virtual destructor Should destructors in a base class be declared as virtual? Why or why not? Virtual destructor Should destructors in a base class be declared as virtual? Why or why not? Yes! We must always clean up the mess created in the subclass (otherwise, risks for memory leaks!) Virtual destructor exampleclass Base1 { public: ~Base1() { std::cout << "~Base1()\n"; } }; class Derived1 : public Base1 { public: ~Derived1() { std::cout << "~Derived1()\n"; } }; class Base2 { public: virtual ~Base2() { std::cout << "~Base2()\n"; } }; class Derived2 : public Base2 { public: ~Derived2() { std::cout << "~Derived2()\n"; } }; int main() { Base1* bp = new Derived1; //Upcast delete bp; Base2* b2p = new Derived2; //Upcast delete b2p; } Courtesy of Bruce Eckel, from Thinking in C++. Used with permission. Virtual destructor in MITPersonclass MITPerson { protected:int id; std::string name;std::string address; public: MITPerson(int id, std::string name, std::string address); ~MITPerson(); virtual void displayProfile();virtual void changeAddress(std::string newAddress);}; MITPerson::~MITPerson() { } Virtual constructor Can we declare a constructor as virtual? Why or why not? Virtual constructor Can we declare a constructor as virtual? Why or whynot?No, not in C++.To create an object, you must know its exact type.TheVPTR has not even been initialized at this point. Type casting MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); Class* c1 = new Class("6.088"); steve->addClassTaken(c1); What will happen?Type casting MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); Class* c1 = new Class("6.088"); steve->addClassTaken(c1);X Can only invoke methods of the declared type!“addClassTaken” is not a member of MITPersonType casting MITPerson* steve = new Student(911923, "Steve", "99 Cambridge St.", 18, 3); Class* c1 = new Class("6.088"); Student* steve2 = dynamic_cast*(steve); steve2->addClassTaken(c1); //OK Use “dynamic_cast<...>” to downcast the pointerStatic vs. dynamic casting Can also use “static_cast<...>” Student* steve2 = static_cast*(steve); Cheaper but dangerous! No runtime check! MITPerson* p = MITPerson(...); Student* s1 = static_cast*(p); //s1 is not checked! Bad! Student* s2 = dynamic_cast*(p); //s2 is set to NULL Use “static_cast<...>” only if you know what you are doing! Abstract base classAbstract methods Sometimes you want to inherit only declarations, not definitions A method without an implementation is called an abstract method Abstract methods are often used to create an interface Example: Binary search tree Can provide multiple implementations to BSTimplementsArray BST insert print find BST insert print find Node BST insert print find implements Decouples the client from the implementations Defining abstract methods in C++Use pure virtual functions class BST { public:virtual ~BST() = 0;virtual void insert(int val) = 0; virtual bool find(int val) = 0; virtual void print_inorder() = 0; }; (How would you do this in Java?)Defining abstract methods in C++ Use pure virtual functions class BST {this says that “find” is pure (i.e. no implementation)public: virtual ~BST() = 0; virtual void insert(int val) = 0; virtual void print_inorder() = 0;virtual bool find(int val) = 0;}; this says that “find” is virtualDefining abstract methods in C++Can we have non-virtual pure functions? class BST { public:virtual ~BST() = 0;virtual void insert(int val) = 0; virtual bool find(int val) = 0; virtual void print_inorder() = 0; }; Abstract classes in C++ Abstract base class �a class with one or more pure virtual functions �cannot be instantiated BST bst = new BST(); //can’t do this!�its subclass must implement the all of the pure virtual functions (or itself become an abstract class) Extending an abstract base class class NodeBST : public BST { Node* root; public:NodeBST();~NodeBST();void insert(int val);bool find(int val);void print_inorder();}; //implementation of the insert method using nodes void NodeBST::insert(int val) { if (root == NULL) { root = new Node(val); } else { ... } } Constructors in abstract classesDoes it make sense to define a constructor? The class will never be instantiated! Constructors in abstract classes Does it make sense to define a constructor? The class will never be instantiated! Yes! You should still create a constructor to initialize its members, since they will be inherited by its subclass. Destructors in abstract classes Does it make sense to define a destructor? The class will never be created in the first place.Destructors in abstract classes Does it make sense to define a destructor? The class will never be created in the first place.Yes! Always define a virtual destructor in the base class, to make sure that the destructor of its subclass is called!Pure virtual destructor Can also define a destructor as pure.class BST { public: virtual ~BST() = 0; virtual void insert(int val) = 0; virtual bool find(int val) = 0; virtual void print_inorder() = 0; }; But must also provide a function body.Why?BST::~BST() {} Until next time... Homework #5 (due 11:59 PM Tuesday) �Designing & implementing type hierarchy for simple arithmetic expressions Next lecture �templates �common C++ pitfalls �C/C++ interview questions & tricks 58References Thinking in C++ (B. Eckel) Free online edition!Essential C++ (S. Lippman)Effective C++ (S. Meyers)C++ Programming Language (B. Stroustrup)Design Patterns (Gamma, Helm, Johnson,Vlissides)Object-Oriented Analysis and Design with Applications (G. Booch, et. al)59 Extra slidesSubtype: Student #include #include #include "MITPerson.h" what if this is private? #include "Class.h" class Student : public MITPerson { int course;int year; //1 = freshman, 2 = sophomore, etc.std::vector classesTaken; public: Student(int id, std::string name, std::string address, int course, int year);void displayProfile();void addClassTaken(Class* newClass);void changeCourse(int newCourse); }; MIT OpenCourseWarehttp://ocw.mit.edu 6.088 Introduction to C Memory Management and C++ Object-Oriented Programming January IAP 2010 For information about citing these materials or our Terms of Use, visit: http://ocw.mit.edu/terms.

Description
This lecture notes introduces Inheritance and polymorphism; templates; standard library containers and Abstract base classes.A subtype inherits characteristics and behaviors of its base type.Public,Protected and Private
are different types of Access control.

“Eunsuk Kang & Jean Yang, 6.088-6 Inheritance and polymorphism; templates; standard library containers,6.088 Introduction to C Memory Management and C++ Object-Oriented Programming, Electrical Engineering and Computer Science, Engineering, Massachusetts Institute of Technology: MIT Open Course Ware,http://ocw.mit.edu (22-08-2011).License: Creative Commons BY-NC-SA: http://ocw.mit.edu/terms/#cc".

Comments

Want to learn?

Sign up and browse through relevant courses.

Name:
Your Email:
Password:
Country:
Contact no:


Area code Number
Subjects you are interested in:
Word verification: (Enter the text as in image)


Sign Up Already a member? Sign In
I agree to WizIQ's User Agreement & Privacy Policy
LearnOnline Through OCW
OpenCourseWare
User
102 Followers

Your Facebook Friends on WizIQ

Explore Similar Courses

Program in C++

Price:$149

Give live classes, create & sell online courses

Try it free Plans & Pricing

Connect