Self-test 4:
Inheritance and Virtual Function
-
The inheritance mechanism provides a means of deriving:
- a new class from an existing class.
- a new operator from an existing operator.
- a new set of memory allocation functions from the built-in ones.
- All of the above.
SolutionA is correct. Inheritance is a means of reusing code effectively. To derive a new operator from an existing operator or to derive a new set of memory allocation functions from the built-in ones is called operator overloading.
-
The ___________ member function is declared in the base class but is redefined in the derived class to override the one in the base class.
- class
- overloaded
- virtual
- operator
SolutionC is correct. Redefining virtual functions is called overriding as opposed to overloading.
-
State whether each of the following is true or false. If false, explain why.
- Base class constructors are not inherited by derived class.
- A has-a relationship is implemented via public inheritance.
- Inheritance encourages the reuse of proven high-quality software.
- When a derived-class object is destroyed, the destructors are called in the reverse order of the constructors.
SolutionA) True. B) False. A has-a relationship is implemented via composition. A is-a relationship is implemented via public inheritance. C) True. D) True.
-
What is the output of following program?
#include<iostream> using namespace std; class P { public: void print() { cout <<" Inside P"; } }; class Q : public P { public: void print() { cout <<" Inside Q"; } }; class R: public Q { }; int main(void) { R r; r.print(); return 0; }
- Inside P
- Inside Q
- Nothing since class R doesn't define the print( ) function
- Compilation error: Ambiguous call to print( )
SolutionB is correct. The print function is not present in class R. So it is looked up in the inheritance hierarchy. print() is present in both classes P and Q, which of them should be called? The idea is, if there is multilevel inheritance, then function is linearly searched up in the inheritance hierarchy until a matching function is found.
-
What is the output of following program?
#include<iostream> using namespace std; class Base { public: void show() { cout<<" In Base "; } }; class Derived: public Base { public: int x; void show() { cout<<"In Derived "; } Derived() : x(10) { } }; int main(void) { Base *bp, b; Derived d; bp = &d; bp->show(); cout << bp->x; return 0; }
- Compilation error for the line " bp->show()"
- Compilation error for the line " cout << bp->x"
- In Base 10
- In Derived 10
SolutionB is correct. A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer.
-
Use of virtual functions implies:
- overloading.
- static binding.
- dynamic binding.
SolutionC is correct. Generally, virtual functions are mainly used when we need to do dynamic binding.
-
What is the output of following program?
#include<iostream> using namespace std; class Base { public: virtual void show() { cout<<" In Base\n"; } }; class Derived: public Base { public: void show() { cout<<"In Derived\n"; } }; int main(void) { Base *bp = new Derived; bp->show(); Base &br = *bp; br.show(); return 0; }
- In Base
In Base - In Base
In Derived - In Derived
In Derived - In Derived
In Base
SolutionC is correct. Since show( ) is a virtual function in the base class, it is also virtual in the derived class. It is called according to the type of object being referenced or pointed, rather than the type of pointer or reference.
- In Base
-
What is the output of following program?
#include<iostream> using namespace std; class Base { public: virtual void show() = 0; }; int main(void) { Base b; Base *bp; return 0; }
- There are compilation errors in lines "Base b;" and "Base bp;"
- There is compilation error in line "Base b;
- There is compilation error in line "Base bp;"
- No compilation error
SolutionB is correct. Since Base has a pure virtual function, it becomes an abstract class and an instance of it cannot be created. So there is an error in line "Base b". Note that there is no error in line "Base *bp;". We can have pointers or references of abstract classes.
-
What is the output of following program?
#include<iostream> using namespace std; class A { public: virtual void fun() { cout << "A::fun() "; } }; class B: public A { public: void fun() { cout << "B::fun() "; } }; class C: public B { public: void fun() { cout << "C::fun() "; } }; int main() { B *bp = new C; bp->fun(); return 0; }
- A::fun()
- B::fun()
- C::fun()
SolutionC is correct. The important thing to note here is B::fun() is virtual even if we have not uses virtual keyword with it. When a class has a virtual function, functions with the same signature in all its descendant classes automatically become virtual. We don't need to use the virtual keyword in declaration of fun( ) in B and C. They are anyways virtual, but it is a good practice to add the virtual keyword to those functions in the derived classes.
-
What is the output of following program?
#include<iostream> using namespace std; class Base { public: virtual void show() { cout << "In Base\n"; } }; class Derived: public Base { public: virtual void show() { cout << "In Derived\n"; } }; int main(void) { Base *bp = new Derived; bp->Base::show(); // Note the use of scope resolution here return 0; }
- In Base
- In Derived
- Compilation error
- Runtime Error
SolutionA is correct. A base class function can be accessed with scope resolution operator even if the function is virtual.