1 CSCI 104 Inheritance Mark Redekopp David Kempe
2 Files for Today • $ mkdir inh • $ cd inh • $ wget http://ee.usc.edu/~redekopp/cs104/inh.tar • $ tar xvf inh.tar • $ make
3 Constructor Initialization Lists class Person{ public: Person(); Person(string myname); Person(string myname, int myid); string get_name() { return name; } void add_grade(int score); int get_grade(int index); private: string name_; int id_; }; Person::Person() { } string name_ Person::Person(string myname) { name_ = myname; int id_ id_ = -1; } Person::Person(string myname, int myid) { name_ = myname; id_ = myid; } ... • C++ constructors often have a bunch of assignments and initializations to the data members.
4 Constructor Initialization Lists Person::Person(string myname) : Person::Person() /* mem allocated here */ name(myname), id(12313) { { } name("Tommy Trojan"); id = 12313; } You would have to call the member You can't call member constructors in the {…} constructors in the initialization list context • Rather than writing many assignment statements we can use a special initialization list technique for C++ constructors – Constructor(param_list) : member1(param/val), …, memberN(param/val) { … } • We are really calling the respective constructors for each data member
5 Constructor Initialization Lists Person::Person() : Person::Person() name(), id() { // calls to default constructors name = "Tommy Trojan"; { id = 12313 name = "Tommy Trojan"; } id = 12313 } But any member not in the initialization list will You can still assign data members in the {…} have its default constructor invoked before the {…} • You can still assign values in the constructor but realize that the default constructors will have been called already • So generally if you know what value you want to assign a data member it's good practice to do it in the initialization list
6 Constructor Initialization Lists Person::Person() { } Person::Person(string myname) Memory is string name_ { name_ = myname; allocated id_ = -1; int id_ before the '{' … } Person::Person(string myname, int myid) { name_ = myname; id_ = myid; …then values } name_ = myname copied in when ... id_ = myid assignment String Operator=() Called performed Initialization using assignment Person::Person() { } Memory is name_ = myname Person::Person(string myname) : allocated and name_(myname), id_(-1) id_ = myid filled in "one- { } step" Person::Person(string myname, int myid) : name_(myname), id_(myid) { } ... String Copy Constructor Called Initialization List approach
7 INHERITANCE
8 Object Oriented Design • Encapsulation – Combine data and operations on that data into a single unit (e.g. a class w/ public and private aspects) • Inheritance – Creating new objects (classes) from existing ones • Polymorphism – Using the same expression to denote different operations
9 Inheritance • A way of defining interfaces, re-using classes and extending original functionality • Allows a new class to inherit all the data members and member functions from a previously defined class • Works from more general objects to more specific objects – Defines an “is - a” relationship – Square is-a rectangle is-a shape – Square inherits from Rectangle which base inherits from Shape child – Similar to classification of organisms: grandchild • Animal -> Vertebrate -> Mammals -> Primates
10 Base and Derived Classes • Derived classes inherit class Person { public: Person(string n, int ident); all data members and string get_name(); int get_id(); private: functions of base class string name_; int id_; }; class Student : public Person { • Student class inherits: public: Student(string n, int ident, int mjr); int get_major(); – get_name() and get_id() double get_gpa(); void set_gpa(double new_gpa); – name_ and id_ member private: int major_; double gpa_; }; variables Class Person Class Student string name_ string name_ int id_ int id_ int major_ double gpa_
11 Base and Derived Classes • Derived classes inherit class Person { public: Person(string n, int ident); all data members and string get_name(); int get_id(); private: functions of base class string name_; int id_; }; class Student : public Person { • Student class inherits: public: Student(string n, int ident, int mjr); int get_major(); – get_name() and get_id() double get_gpa(); void set_gpa(double new_gpa); – name_ and id_ member private: int major_; double gpa_; variables }; int main() { Class Person Class Student Student s1("Tommy", 1, 9); string name_ string name_ // Student has Person functionality // as if it was written as part of int id_ int id_ // Student cout << s1.get_name() << endl; int major_ double gpa_ }
12 Inheritance Example Inheritance Diagrams (arrows shown base Component to derived class • Component relationships) – Draw() Window ListBox – onClick() • Window – Minimize() ScrollBox DropDown – Maximize() Box • ListBox – Get_Selection() • Scroll Box – onScroll() • DropDownBox – onDropDown()
13 Constructors and Inheritance • How do we initialize base class Person { public: Person(string n, int ident); class data members? ... private: • Can't assign base class string name_; int id_; members if they are }; class Student : public Person { private public: Student(string n, int ident, int mjr); ... private: int major_; double gpa_; }; Student::Student(string n, int ident, int mjr) { name_ = n; // can't access name_ in Student id_ = ident; major_ = mjr; }
14 Constructors and Inheritance • Constructors are only called when class Person { public: a variable ‘enters scope’ (i.e. is Person(string n, int ident); created) and cannot be called ... private: directly string name_; int id_; – How to deal with base }; constructors? class Student : public Person { public: • Also want/need base class or Student(string n, int ident, int mjr); ... other members to be initialized private: before we perform this object's int major_; double gpa_; constructor code }; • Student::Student(string n, int ident, int mjr) Use initializer format instead { – See example below // How to initialize Base class members? Person(n, ident); // No! can’t call Construc. // as a function } Student::Student(string n, int ident, int mjr) : Person(n, ident) { cout << "Constructing student: " << name_ << endl; major_ = mjr; gpa_ = 0.0; }
15 Constructors & Destructors • Constructors – A Derived class will automatically call its Base class constructor BEFORE it's own constructor executes, either: base • Explicitly calling a specified base class constructor in the child initialization list grandchild • Implicitly calling the default base class constructor if no base class constructor is called in the initialization list Constructor call ordering • Destructors – The derived class will call the Base class destructor automatically AFTER it's own destructor executes • General idea – Constructors get called from base->derived (smaller to base larger) child – Destructors get called from derived->base (larger to grandchild smaller) Destructor call ordering
16 Constructor & Destructor Ordering class A { int main() int a; { public: cout << "Allocating a B object" << endl; A() { a=0; cout << "A:" << a << endl; } B b1; ~A() { cout << "~A" << endl; } cout << "Allocating 1st C object" << endl; A(int mya) { a = mya; C* c1 = new C; cout << "A:" << a << endl; } cout << "Allocating 2nd C object" << endl; }; C c2(4,5); cout << "Deleting c1 object" << endl; class B : public A { delete c1; int b; cout << "Quitting" << endl; public: return 0; Test Program B() { b = 0; cout << "B:" << b << endl; } } ~B() { cout << "~B "; } B(int myb) { b = myb; Allocating a B object A:0 cout << "B:" << b << endl; } }; B:0 Allocating 1st C object A:0 class C : public B { int c; B:0 C:0 public: C() { c = 0; cout << "C:" << c << endl; } Allocating 2nd C object A:0 ~C() { cout << "~C "; } B:4 C(int myb, int myc) : B(myb) { c = myc; C:5 Deleting c1 object cout << "C:" << c << endl; } }; ~C ~B ~A Quitting Sample Classes ~C ~B ~A Output ~B ~A
17 Protected Members • Private members of a base class Person { public: class can not be accessed ... private: directly by a derived class string name_; int id_; }; member function class Student : public Person { public: – Code for print_grade_report() void print_grade_report(); private: would not compile since ‘name_’ is int major_; double gpa_; private to class Person }; • Base class can declare void Student::print_grade_report() { variables with protected X cout << “Student “ << name_ << ... } storage class – Private to anyone not inheriting class Person { from the base public: – Derived classes can access directly ... protected: string name_; int id_; };
More recommend