0% found this document useful (0 votes)
2 views

PPT7 Inheritance Part 2

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views

PPT7 Inheritance Part 2

Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 34

UTA 018: OOPs

Inheritance Part 2

1
Content
• Constructor and Destructor in Inheritance
• Inheritance and Static Functions
• Virtual class
• Abstract Class
• Pure Virtual Functions
• Polymorphism
• Overloading and Overriding
Constructor and Destructor in Inheritance
Constructors and Destructors in Base and
Derived Classes
• Derived classes can have their own constructors and destructors.
• When an object of a derived class is created, the base class’s
constructor is executed first, followed by the derived class’s
constructor.
• When an object of a derived class is destroyed, its destructor is called
first, then that of the base class.

4
//EXAMPLE ~derived()
#include<iostream> { cout << "Destructing derived\n"; }
Using namespace std; };

//base class int main()


{
class base {
derived ob;
public:
// do nothing but construct and destruct ob
base() { cout << "Constructing base\n"; }
return 0;
~base() { cout << "Destructing base\n"; }
}
};
Program Output
//derived class Constructing base
class derived: public base { Constructing derived
Destructing derived
public: Destructing base
derived() { cout << "Constructing derived\n"; }
5
Constructors and Destructors with Multiple Base
Classes
• Constructors are called in order of derivation, left to right, as
specified in derived's inheritance list.
• Destructors are called in reverse order, right to left.

6
//MULTI-LEVEL class derived2: public derived1 {
#include <iostream> public:
using namespace std; derived2()
class base { { cout << "Constructing derived2\n"; }
public: ~derived2()
base() { cout << "Destructing derived2\n"; }
{ cout << "Constructing base\n"; } };
~base() int main()
{ cout << "Destructing base\n"; } {
}; derived2 ob;
class derived1 : public base { // construct and destruct ob
public: return 0;
Program Output:
derived1() } Constructing base
{ cout << "Constructing derived1\n"; } Constructing derived1
~derived1() Constructing derived2
Destructing derived2
{ cout << "Destructing derived1\n"; } Destructing derived1
}; Destructing base
7
//MULTIPLE BASE CASES class derived: public base1, public base2 {
#include <iostream> public:
using namespace std; derived()
class base1 { { cout << "Constructing derived\n"; }
public: ~derived()
base1() { cout << "Destructing derived\n"; }
{ cout << "Constructing base1\n"; } };
~base1() int main()
{ cout << "Destructing base1\n"; } {
}; derived ob;
class base2 { // construct and destruct ob
public: return 0; Program Output:
base2() } Constructing base1
{ cout << "Constructing base2\n"; } Constructing base2
~base2() Constructing derived
Destructing derived
{ cout << "Destructing base2\n"; }
Destructing base2
}; Destructing base1

8
Important Note:
Besides being unable to directly access private members of a parent
class, several parent class members are never inherited:
• » constructors
• » destructors
• » friend functions
• » overloaded new operators
• » overloaded = operators
If a derived class requires any of the preceding items, the item must be
explicitly defined within the derived class definition
Question:1
If a derived class uses the public access specifier for inheritance, then
which of the following statements are true:
A. Base class members that are public remain public in the derived
class.
B. Base class members that are protected become public in the
derived class.
C. Base class members that are private are inaccessible in the derived
class.
D. None of the Above
Question:2
If a derived class uses the protected access specifier for inheritance,
then which of the following statements are true:
A. Base class members that are public remain public in the derived
class.
B. Base class members that are protected remain protected in the
derived class.
C. Base class members that are private are inaccessible in the derived
class.
D. None of the above
Question:3
If a derived class uses the private access specifier for inheritance, then
which of the following statements are true:
A. Base class members that are public become private in the derived
class.
B. Base class members that are protected become private in the
derived class.
C. Base class members that are private are inaccessible in the derived
class.
D. None of the above
Question:4
Class A serves as a base class to class B, and B is a parent to class C.
When you instantiate a class B object, the first constructor called
belongs to class ___________ .
a. A
b. B
c. C
d. none of the above
Question:5
Class A contains a nonstatic void public function named functionA()
that requires an integer argument. Class B derives from class A, and
also contains a nonstatic void public function named functionA() that
requires an integer argument. An object of class B can use
___________ .
a. the class A version of the function
b. the class B version of the function
c. both of the above
d. none of the above
Practice Question
Passing Arguments to Base Class Constructor
derived-constructor(arg-list) : base1(arg-list), base2(arg-list),// ... baseN(arg-list)
{
// body of derived constructor
}

16
Order of Constructor Call
• Base class constructors are always called in the derived class
constructors.
• Whenever you create derived class object, first the base class default
constructor is executed and then the derived class's constructor
finishes execution.

17
//EXAMPLE // derived uses x; y is passed along to base.
#include <iostream> derived(int x, int y): base(y)
using namespace std; { j=x;
class base { cout << "Constructing derived\n"; }
protected: ~derived()
int i; { cout << "Destructing derived\n"; }
public: void show()
base(int x) { cout << i << " " << j << "\n"; }
{ i=x; };
cout << "Constructing base\n"; } int main()
~base() { cout << "Destructing base\n"; } {
}; derived ob(3, 4);
class derived: public base { ob.show(); // displays 4 3
int j; return 0;
public: }

18
//MULTIPLE BASE CASES class derived: public base1, public base2 {
#include <iostream> int j;
using namespace std; public:
class base1 { derived(int x, int y, int z): base1(y), base2(z)
protected: int i; { j=x; cout << "Constructing derived\n"; }
public: ~derived() { cout << "Destructing derived\n"; }
base1(int x) void show() { cout << i << " " << j << " " << k << "\n"; }
{ i=x; cout << "Constructing base1\n"; } };
~base1() { cout << "Destructing base1\n"; }}; int main()
class base2 { { derived ob(3, 4, 5);
protected: int k; ob.show(); // displays 4 3 5
public: return 0; }
base2(int x) { k=x; cout << "Constructing base2\n"; }
~base2() { cout << "Destructing base1\n"; } };

19
Here’s what actually happens when derived is instantiated:

• Memory for derived is set aside (enough for both the Base and
Derived portions)
• The appropriate Derived constructor is called
• The Base object is constructed first using the appropriate Base
constructor. If no base constructor is specified, the default
constructor will be used.
• The initialization list initializes variables
• The body of the constructor executes
• Control is returned to the caller

20
Points to note
• It is important to understand that arguments to a base-class
constructor are passed via arguments to the derived class' constructor.

• Even if a derived class‘ constructor does not use any arguments, it will
still need to declare one if the base class requires it.

• In this situation, the arguments passed to the derived class are simply
passed along to the base.

21
Why is Base class Constructor called inside Derived class?
• Constructors have a special job of initializing the object properly.
• A Derived class constructor has access only to its own class members,
but a Derived class object also have inherited property of Base class,
and only base class constructor can properly initialize base class
members.
• Hence all the constructors are called, else object wouldn't be
constructed properly.

22
// This program contains an error and will int main() {
not compile. derived3 ob;
#include <iostream> ob.i = 10; // this is ambiguous, which
i???
using namespace std;
ob.j = 20;
class base { ob.k = 30;
public: int i; }; // i ambiguous here, too
class derived1 : public base { ob.sum = ob.i + ob.j + ob.k;
public: int j; }; // also ambiguous, which i?
class derived2 : public base { cout << ob.i << " ";
public: int k; }; cout << ob.j << " " << ob.k ;
cout << ob.sum;
class derived3 : public derived1, public
derived2 { return 0;
public: int sum; }; }

23
Discussion
• which ‘i’ is being referred to, the one in derived1 or the one in
derived2?
• Because there are two copies of base present in object ob, there are
two ob.is! ->, the statement is inherently ambiguous.
• There are two ways to remedy the preceding program.
• The first is to apply the scope resolution operator to i and manually
select one i. Example (on next slide).

24
// This program uses explicit scope int main()
resolution to select i.
{
#include <iostream>
derived3 ob;
using namespace std;
ob.derived1::i = 10; // scope resolved, use
class base { public: int i; }; derived1's i
// derived1 inherits base. ob.j = 20;
class derived1 : public base {
ob.k = 30;
public: int j; };
// scope resolved
// derived2 inherits base.
ob.sum = ob.derived1::i + ob.j + ob.k;
class derived2 : public base {
// also resolved here
public: int k; };
cout << ob.derived1::i << " ";
class derived3 : public derived1, public
derived2 { cout << ob.j << " " << ob.k << " ";
public: int sum; }; cout << ob.sum;
return 0; }

26
Discussion
• As you can see, because the :: was applied, the program has
manually selected derived1's version of base.
• What if only one copy of base is actually required? Is there some way
to prevent two copies from being included in derived3?
• This solution is achieved using virtual base classes.

27
• When two or more objects are derived from a common base class, you
can prevent multiple copies of the base class from being present in an
object derived from those objects by declaring the base class as virtual
when it is inherited.
• You accomplish this by preceding the base class' name with the
keyword virtual when it is inherited.
• For example, here is another version of the example program in which
derived3 contains only one copy of base:

Example Program Next


Slide

28
// This program uses virtual base classes. int main()
#include <iostream>
{
using namespace std;
class base { public: int i; }; derived3 ob;
ob.i = 10; // now unambiguous
// derived1 inherits base as virtual. ob.j = 20;
ob.k = 30;
class derived1 : virtual public base {
public: int j; }; // unambiguous
ob.sum = ob.i + ob.j + ob.k;
// derived2 inherits base as virtual. // unambiguous
cout << ob.i << " ";
class derived2 : virtual public base {
public: int k; }; cout << ob.j << " " << ob.k << " ";
cout << ob.sum;
class derived3 : public derived1, public derived2 return 0;
{ public: int sum; };
}
29
Discussion
• As you can see, the keyword virtual precedes the rest of the inherited
class‘specification.
• Now that both derived1 and derived2 have inherited base as virtual,
any multiple inheritance involving them will cause only one copy of
base to be present.
• Therefore, in derived3, there is only one copy of base and ob.i = 10 is
perfectly valid and unambiguous.

30
class A {
public: void show() {cout<<"In A"<<endl;}
};

class B : public A {};


class C : public A {};
class D : public B, public C {};

int main() {D d; d.show(); }


Output

[Error] request for member 'show' is ambiguous

Need virtual keyword to fix this error


class A {
public: void show() {cout<<"In A"<<endl;}
};

class B : public virtual A {};


class C : public virtual A {};
class D : public B, public C {};

int main() {D d; d.show(); }


cout<<"In Use"<<endl;
return 0;
}

You might also like