Public and Private and Protected Inheritance can be combined
Memory can become very tricky
Syntax:
class A{ int a; ...};
class B{int b; ...};
class C : public A, pulic B {int c; ...};
// C has public base classes A and B
a C object will have memmory: A::a, B::b, C::c
class D: pulic A, private B {int d; ...};
//D has public base class A and private base
class
B
a D object will have memory A::a, B::b, D::d;
Public inheritance is appropriate for "is a" relationships
class BankAccount{public: deposit(float
amount);
...}
class SavingAccount : public BankAccount {
...};
SavingAccount s;
s.deposit(100); //inherits bank account behaviour
A SavingAccount is a BankAcount
Multiple
inheritance allows objects to represent several (disjoint) types.
class Phone{public: dial(); ...};
class Graphic{ public: draw(); ...};
class PhoneWindow : public Phone, public Graphic {....}
updateWindow(Graphic * gp) {gp->draw(); }
makeCall(Phone * pp) {pp->dial(); }
PhoneWindow * p = new PhoneWindow;
makeCall(p); //p being used as Phone pointer
updateWindow(p); //p being used as Graphic
pointer
A PhoneWindow is a Phone
and it is a Graphic
But, memory becomes tricky in these
situations:
#include
<iostream.h>
class A{
int a1,a2;
};
class B{
int b1,b2, b3;
};
class C : public A, public B{
int c1,c2;
};
void fooA(A & anA) {
cout <<
"fooA: " << &anA << "\n";
}
void fooB(B & aB) {
cout <<
"fooB: " << &aB << "\n";
}
void main(void) {
C ac;
cout << "main:
" << &ac << "\n";
fooA(ac);
fooB(ac);
}
/*OUTPUT
main:
0x0012FF64
fooA:
0x0012FF64
fooB:
0x0012FF6C ----why different
*/
Public inheritance is
appropriate
for "is a" relationships
Private inheritance is
approriate
for a "part of" relationship
class Vector{public: operator[](int i); ...}
class Stack {public: void push(T & item);
T & pop(); ...};
class MyStack : public Stack, private Vector { ...};
MyStack s;
s.push(x); s.pop(); //OK
s[3] = x; //ERROR the [] operator is private
A MyStack is a
Stack,
but a Vector is part of MyStack
(Clients of MyStack are not
aware that it has Vector properties
Protected inheretance
allows
further subclassing; private inheritance does not
Example1:
class A{int a; ...}
class B1 : public A { int b1; ...};
class B2 : public A { int b2; ...};
class C : public B1, public B2 {int c; ...};
a C object will have memory
A::a,
B1::b1,
A::a,
B2::b2,
C::c
(Notice common base class
memory
is repeated)
Example2 (Virtual Inheritance)
class A{int a; ...}
class B : virtual
public A { int b1; ...};
class B2 : virtual
public A { int b2; ...};
class C : public B1, public B2 {int c; ...};
a C object will have memory
A::a,
B1::b1,
B2::b2,
C::c
(Notice common base class memory is NOT repeated)
#include
<iostream>using
namespace std;
//Multiple inheritance with common base class
//example 1
class
A {public
:A() {cout << "A()\n";}
A(int i) {cout << "A(int)\n";}
};
class
B1 : public A {public
:B1(): A(5) {cout << "B1()\n";}
};
class
B2: public A {public
:B2() {cout << "B2()\n";}
};
class
C: public B1, public B2 {public
:C() {cout << "C()\n";}
};
void
main() {C c;
}
/*OUTPUT
A(int)
B1()
A()
B2()
C()
END OUTPUT */
#include <iostream.h>
class A {
public:
A() :mA(0) {cout <<
"A()\n";}
A(int i): mA(i) {cout
<<
"A(int)\n";}
~A() {cout << "~A()\n";}
void print() {cout <<
"mA= " << mA <<"\n";}
private:
int mA;
};
class B1 : public A {
public:
B1(): mB1(0) {cout <<
"B1()\n";}
~B1() {cout <<
"~B1()\n";}
void print() {A::print();
cout << "mB1=
" << mB1 <<"\n";}
private:
int mB1;
};
class B2: public A {
public:
B2() : mB2(0){cout <<
"B2()\n";}
B2(int i) : mB2(i), A(i)
{cout << "B2()\n";}
~B2() {cout <<
"~B2()\n";}
void print() {A::print();
cout << "mB2=
" << mB2 <<"\n";}
private:
int mB2;
};
class C: public B1, public B2 {
public:
C(): mC(0) {cout <<
"C()\n";}
C(int i): mC(i), B2(i) {cout
<< "C()\n";}
~C() {cout << "~C()\n";}
void print() {B1::print();
B2::print();
cout <<
"mC= " << mC << "\n"; }
private:
int mC;
};
void main() {
C c(5);
c.print();
}
/*OUTPUT
A()
B1()
A(int)
B2()
C()
mA= 0
mB1= 0
mA= 5
mB2= 5
mC= 5
~C()
~B2()
~A()
~B1()
~A()
END OUTPUT
*/
class A {
public:
A() :mA(0) {cout <<
"A()\n";}
A(int i): mA(i) {cout
<<
"A(int)\n";}
virtual ~A() {cout <<
"~A()\n";}
virtual void print() {cout
<< "mA= " << mA <<"\n";}
private:
int mA;
};
class B1 : public A
{
public:
B1(): mB1(0) {cout <<
"B1()\n";}
B1(int i): A(i),
mB1(i) {cout << "B1()\n";}
~B1() {cout << "~B1()\n";}
void print() {A::print();
cout << "mB1=
" << mB1 <<"\n";}
private:
int mB1;
};
class B2: public A {
public:
B2() : mB2(0){cout <<
"B2()\n";}
B2(int i) : mB2(i), A(i)
{cout << "B2()\n";}
~B2() {cout <<
"~B2()\n";}
void print() {A::print();
cout << "mB2=
" << mB2 <<"\n";}
private:
int mB2;
};
class C: public B1, public B2 {
public:
C(): mC(0) {cout <<
"C()\n";}
C(int i): mC(i), B1(i*10),
B2(i) {cout << "C()\n";}
~C() {cout << "~C()\n";}
void print() {B1::print();
B2::print();
cout <<
"mC= " << mC << "\n"; }
private:
int mC;
};
void main() {
C *p = new C(5); //A *p
would be ambiquous
//B1 *p or B2 *p OK but need virtual destructors
//and methods (like print)
p->print();
delete p;
}
/*OUTPUT
A(int)
B1()
A(int)
B2()
C()
mA= 50
mB1= 50
mA= 5
mB2= 5
mC= 5
~C()
~B2()
~A()
~B1()
~A()
END OUTPUT
*/
class A {
public:
A() :mA(0) {cout <<
"A()\n";}
A(int i): mA(i) {cout
<<
"A(int)\n";}
virtual ~A() {cout <<
"~A()\n";}
virtual void print() {cout
<< "mA= " << mA <<"\n";}
private:
int mA;
};
class B1 : virtual
public
A {
public:
B1(): mB1(0) {cout <<
"B1()\n";}
B1(int i): A(i),
mB1(i) {cout << "B1()\n";}
~B1() {cout << "~B1()\n";}
void print() {A::print();
cout << "mB1=
" << mB1 <<"\n";}
private:
int mB1;
};
class B2: virtual
public
A {
public:
B2() : mB2(0){cout <<
"B2()\n";}
B2(int i) : mB2(i), A(i)
{cout << "B2()\n";}
~B2() {cout <<
"~B2()\n";}
void print() {A::print();
cout << "mB2=
" << mB2 <<"\n";}
private:
int mB2;
};
class C: public B1, public B2 {
public:
C(): mC(0) {cout <<
"C()\n";}
C(int i): mC(i), B1(i*10),
B2(i) {cout << "C()\n";}
~C() {cout << "~C()\n";}
void print() {B1::print();
B2::print();
cout <<
"mC= " << mC << "\n"; }
private:
int mC;
};
void main() {
A *p = new C(5); //notice
A *p not ambiquous
p->print();
delete p;
}
/*OUTPUT
A()
//notice A(int) not called
B1()
B2()
C()
mA= 0
mB1= 50
mA= 0
mB2= 5
mC= 5
~C()
~B2()
~B1()
~A()
END OUTPUT
*/
class A {
public:
A() :mA(0) {cout <<
"A()\n";}
A(int i): mA(i) {cout
<<
"A(int)\n";}
virtual ~A() {cout <<
"~A()\n";}
virtual void print() {cout
<< "mA= " << mA <<"\n";}
private:
int mA;
};
class B1 : virtual
public
A {
public:
B1(): mB1(0) {cout <<
"B1()\n";}
B1(int i): A(i),
mB1(i) {cout << "B1()\n";}
~B1() {cout << "~B1()\n";}
void print() {A::print();
cout << "mB1=
" << mB1 <<"\n";}
private:
int mB1;
};
class B2: virtual
public
A {
public:
B2() : mB2(0){cout <<
"B2()\n";}
B2(int i) : mB2(i), A(i)
{cout << "B2()\n";}
~B2() {cout <<
"~B2()\n";}
void print() {A::print();
cout << "mB2=
" << mB2 <<"\n";}
private:
int mB2;
};
class C: public B1, public B2 {
public:
C(): mC(0) {cout <<
"C()\n";}
C(int i): mC(i), B1(i*10),
B2(i), A(i) {cout << "C()\n";}
//A(i) not allowed without virtual inheritance
~C() {cout << "~C()\n";}
void print() {B1::print();
B2::print();
cout <<
"mC= " << mC << "\n"; }
private:
int mC;
};
void main() {
A *p = new C(5);
p->print();
delete p;
}
/*OUTPUT
A(int)
//explicitly
called in C(int)
B1()
B2()
C()
mA= 5
mB1= 50
mA= 5
mB2= 5
mC= 5
~C()
~B2()
~B1()
~A()
END OUTPUT
*/
class A {
public:
A() :mA(0) {cout <<
"A()\n";}
A(int i): mA(i) {cout
<<
"A(int)\n";}
virtual ~A() {cout <<
"~A()\n";}
virtual void print() {cout
<< "mA= " << mA <<"\n";}
public:
int mA;
};
class B1 :
public
A {
public:
B1(): mB1(0) {cout <<
"B1()\n";}
B1(int i): A(i),
mB1(i) {cout << "B1()\n";}
~B1() {cout << "~B1()\n";}
void print() {A::print();
cout << "mB1=
" << mB1 <<"\n";}
private:
int mB1;
};
class B2:
public
A {
public:
B2() : mB2(0){cout <<
"B2()\n";}
B2(int i) : mB2(i), A(i)
{cout << "B2()\n";}
~B2() {cout <<
"~B2()\n";}
void print() {A::print();
cout << "mB2=
" << mB2 <<"\n";}
private:
int mB2;
};
class C: public B1, public B2 {
public:
C(): mC(0) {cout <<
"C()\n";}
C(int i): mC(i), B1(i*10),
B2(i) {cout << "C()\n";}
~C() {cout << "~C()\n";}
void print() {B1::print();
B2::print();
cout <<
"mC= " << mC << "\n"; }
private:
int mC;
};
void main() {
C *cp = new C(5);
B1 *b1p = cp;
B2 *b2p = cp;
b1p->mA = 100;
b2p->mA = 200;
b1p->print();
delete b2p;
}
/*OUTPUT
A(int)
B1()
A(int)
B2()
C()
mA= 100
mB1= 50
mA= 200
mB2= 5
mC= 5
~C()
~B2()
~A()
~B1()
~A()
END OUTPUT
*/