CSE 332: C++ Advanced Topics on Inheritance Advanced Topics on Inheritance Multiple inheritance...
-
Upload
laurence-miles -
Category
Documents
-
view
216 -
download
1
Transcript of CSE 332: C++ Advanced Topics on Inheritance Advanced Topics on Inheritance Multiple inheritance...
CSE 332: C++ Advanced Topics on Inheritance
Advanced Topics on Inheritance
• Multiple inheritance allows a derived class to inherit from more than one direct base class
class Bear: public ZooAnimal {/*...*/}; class Panda: public Bear, public Endangered {/*...*/};
• Virtual Inheritance allows the derived class to share the base class, as a single virtual base class – Regardless how often a base class shows up on different
inheritance paths, only one base class will be included
CSE 332: C++ Advanced Topics on Inheritance
Single Inheritanceclass A {
public:
A(int num): aInt(num) {
cout << "A::constructor"<<endl;;}
~A() {
cout <<"A::destructor"<<endl;}
protected:
int aInt;
};
class B: public A {
public:
B(int numa, int numb)
: A(numa), bInt(numb) {
cout << "B::constructor"<<endl;}
~B() {
cout << "B::destructor"<<endl;}
protected:
int bInt;
};
int main (int, char * []){
B b(2, 3);
return 0;
}
Output:
A::constructorB::constructorB::destructorA::destructor
– Order of execution • constructors: base class
first then derived class• destructors: reverse of
constructors
A
B
CSE 332: C++ Advanced Topics on Inheritance
Single Inheritance, continued// A and B are as declared
// in the previous slide
class C: public B {
public:
C(int numa, int numb, string s )
: B(numa, numb), cStr(s) {
cout << "C::constructor"<<endl;}
~C() {
cout << "C::destructor"<<endl;}
protected:
string cStr;
};
int main (int, char * []) {
C c(4, 7, "hello");
return 0;
}
Output:
A::constructorB::constructorC::constructorC::destructorB::destructorA::destructor
A
B
C
CSE 332: C++ Advanced Topics on Inheritance
Multiple Inheritanceclass X {
public:
X(): xChar('D') {cout << "X::default constructor"<<endl;;}
X(char c): xChar(c) {cout << "X::constructor"<<endl;;}
~X() {
cout << "X::destructor"<<endl;}
protected:
char xChar;
};
class Y {
public:
Y(char c): yChar(c) {
cout << "Y::constructor"<<endl;;}
~Y() {cout << "Y::destructor"<<endl;}
protected:
char yChar;
};
class Z : public X, public Y {
public:
Z(char xC,char yC, int num)
: X(xC), Y(yC), zInt(num) {
cout << "Z::constructor"<<endl;}
~Z() {
cout << "Z::destructor"<<endl;}
protected:
int zInt;
};int main (int, char *[])) {Z zObj('z', 'b', 8);return 0; }
Output:X::constructorY::constructorZ::constructorZ::destructorY::destructorX::destructor
X Y
Z
CSE 332: C++ Advanced Topics on Inheritance
Multiple Inheritance, continuedclass MI: public C, public Z {
public:
MI(int numa, int numb, string s, char xC, char yC, int numZ )
: C(numa, numb, s), Z(xC, yC, numZ) {cout << "MI::constructor"<<endl;}
~MI() {cout << "MI::destructor"<<endl;}
protected:
string cStr;
};
int main (int, char * []) { MI mi(2,4,"eve", 'r', 's', 26); return 0;}
Output:
A::constructorB::constructorC::constructorX::constructorY::constructorZ::constructorMI::constructorMI::destructorZ::destructorY::destructorX::destructorC::destructorB::destructorA::destructor
X Y
Z
A
B
C
MI
CSE 332: C++ Advanced Topics on Inheritance
All Base Class Constructors are Called// X and Y as declared previously
class R : public X, public Y {
public:
R(char xC, char yC, int numx): Y(yC), X(xC), rInt(numx) {cout <<
"R::constructor" << endl;}
~R() {
cout << "R::destructor" <<endl;}
protected:
int rInt;
};
class S : public Y, public X {
public:
S(char yC, int numx): Y(yC), sInt(numx) {cout << "S::constructor"<<endl;}
~S() {cout << "S::destructor"<<endl;}
protected:
int sInt;
};
int main (int, char * []) { R r ('x', 'y', 8); return 0;}Output:X::constructorY::constructorR::constructorR::destructorY::destructorX::destructor
int main (int, char * []) { S s('y', 10); return 0;}Output:Y::constructorX::default constructorS::constructorS::destructorX::destructorY::destructor
CSE 332: C++ Advanced Topics on Inheritance
Base Pointer/Reference Type Restricts Interface// Based on LLM Ch. 18.3 and
// today’s studio exercises
Bear * bear_ptr =
new Panda ("bao_bao");
bear_ptr ->print(); // ok
bear_ptr ->toes(); // ok
bear_ptr ->cuddle(); // not ok
bear_ptr ->growl(); // not ok
delete bear_ptr; // ok
Endangered * endangered_ptr =
new Grizzly;
endangered_ptr->print(); // ok
endangered_ptr->toes(); // not ok
endangered_ptr ->cuddle();// not ok
endangered_ptr ->growl(); // not ok
delete endangered_ptr; // ok
Method Classes Declaring It
print AnimalBearEndangeredPandaGrizzly
toes BearPandaGrizzly
growl Grizzly
cuddle Panda
(virtual) destructor
AnimalBearEndangeredPandaGrizzly
CSE 332: C++ Advanced Topics on Inheritance
Member Inheritance from Multiple Base Classes
• When a class has multiple base classes, a derived class can inherit a member with the same name from two or more base classes
• Unqualified uses of that name are ambiguous
// Loosely based on LLM Ch. 18.3
double Gryphon:max_weight() const {
return std::max (Eagle::max_weight_, // scoping necessary
Lion::max_weight_); // scoping necessary
};
• This in turn motivates the use of virtual base classes// Single Animal instance shared by Eagle and Lion parts of Gryphon
class Eagle : virtual public Animal {/*...*/};
class Lion : virtual public Animal {/*...*/};
class Gryphon : public Eagle, public Lion {/*...*/};
CSE 332: C++ Advanced Topics on Inheritance
More About Virtual Base Classes
• Still Polymorphic– Can convert between uses as Derived vs. Base
• Members of virtual Base class normally can be uniquely identified – base class is instantiated only once– if the variable is in both base and derived class,
then derived class has higher precedence– If the member is in 2 derived classes, then it is
still ambiguous• move members up to avoid that, e.g., Animal::max_weight_
• The most derived class controls the initialization of the shared virtual base class
CSE 332: C++ Advanced Topics on Inheritance
Virtual Base Class Constructor/Destructor Order
• Constructors– All virtual base classes
• up each branch of the inheritance lattice, according to order in which immediate base classes were declared
– Non-virtual base classes• up each branch of the inheritance lattice, according to
order in which immediate base classes were declared – Most derived class last
• Destructors (in reverse order of constructors)– Most derived class first– Then each non-virtual base class, moving up lattice– Then each virtual base class, moving up lattice