Week7 Assignment 7 V3 UPDATED
Week7 Assignment 7 V3 UPDATED
Total Marks : 20
September 2, 2021
Question 1
Consider the following classes. [MCQ, Marks 2]
#include<iostream>
using namespace std;
class A{
public:
virtual void f() {}
void g() {}
};
class B : public A{
public:
virtual void g() {}
void h() {}
virtual void i();
};
class C : public B{
public:
void g() {}
virtual void h() {}
};
class D : public C{
public:
void h(){}
};
What will be the virtual function table for class C?
a) A::f(A* const)
C::g(C* const)
C::h(C* const)
B::i(B* const)
b) A::f(A* const)
B::g(B* const)
C::h(C* const)
B::i(B* const)
1
c) A::f(A* const)
B::g(B* const)
B::h(B* const)
C::i(C* const)
d) A::f(A* const)
B::g(C* const)
C::h(C* const)
C::i(C* const)
Answer: a)
Explanation:
All four functions are virtual in the class C. So, there will be four entries in virtual function
table.
Now function f() is not overridden in class B and C. So, the entry for function f() in the
virtual function table of class C will be A::f(A* const).
The function g() is virtual from class B and is overridden in class C. So, the entry for function
g() in VFT of class C will be C::g(C* const).
The function i() is virtual in class B and inherited by class C. Thus, it appears as B::i(B*
const).
The function h() is declared as virtual in class C. So, the entry for function h() in VFT of
class C will be C::h(C* const).
2
Question 2
Consider the code segment below. [MSQ, Marks 2]
#include <iostream>
using namespace std;
int main() {
const char ch = ’a’;
const char *p = &ch;
char *pt = _____________(p); //LINE-1
*pt = ’b’;
cout << *pt;
return 0;
}
a) (const char*)
b) const cast<char*>
c) static cast<char*>
Answer: b)
Explanation:
At LINE-1, p of type const char* needs to be casted to char*. It can be accomplished by
const cast<char*>(p).
3
Question 3
Consider the following program. [MCQ, Marks 2]
#include <iostream>
using namespace std;
class employee {
int emp_id;
string name ;
public:
employee(int _emp_id, string _name) : emp_id(_emp_id), name(_name) {}
void update(string na) const{
reinterpret_cast<employee*>(this)->name = na;
}
void showInfo() const {
cout << emp_id << " : " << name;
}
};
int main(void) {
const employee e(3, "Rajat");
e.update("Ram");
e.showInfo();
return 0;
}
a) 3 : Rajat
b) 3 : Ram
c) 0 : Ram
d) Compilation Error: reinterpret cast from type ’const employee*’ to type ’employee*’
casts away qualifiers
Answer: d)
Explanation:
The object e is declared as constant. The function update is also declared as constant. The
type of this pointer is const employee* cannot be converted to employee* using reinter-
pret cast. Hence, it gives compilation error.
4
Question 4
Consider the code segment below. [MCQ, Mark 2]
#include <iostream>
using namespace std;
class B {
public:
B() { cout << "1" << " "; }
B(int _x) { cout << "11" << " "; }
};
class D1 : virtual public B {
public:
D1(){ cout << "2" << " "; }
D1(int _x) : B(_x) { cout << "22" << " "; }
};
class D2 : virtual public B {
public:
D2(){ cout << "3" << " "; }
D2(int _x) : B(_x) { cout << "33" << " "; }
};
class DD : public D1, public D2 {
public:
DD(){ cout << "4" << " "; }
DD(int _x) : D1(_x), D2(_x) { cout << "44" << " "; }
};
int main() {
DD d(5);
return 0;
}
a) 11 22 33 44
b) 1 22 33 44
c) 1 33 22 44
d) 1 22 1 33 44
Answer: b)
Explanation:
Class DD is inherited from classes D1, and D2. Hence, the constructor of DD will call constructors
of D1 and D2 in that order (note that, the constructors are actually called in the code as D1(x),
D2(x) in the initialization list. However, the order in which they are defined for inheritance
will prevail).
First, D1 is virtually inherited from B (and no B object has been constructed so far for DD). So,
first the default constructor of B will be called followed by parameterized constructor of D1.
Next, D2 is also virtually inherited from B and an B object has been already been constructed
for DD (during construction of D1 object), so parameterized constructor of D2 will be directly
called (no call of any constructor of B).
5
Question 5
Consider the code segment below. [MSQ, Marks 2]
#include<iostream>
using namespace std;
class C1{
int a = 10;
};
class C2{
public:
int b = 20;
};
int main(){
C1 u;
C2 *v = _______________________(&u);
cout << v->b;
return 0;
}
Fill in the blank at LINE-1, such that output of the code is:
10
a) (C2*)
b) static cast<C2*>
c) reinterpret cast<C2*>
d) dynamic cast<C2*>
Answer: a), c)
Explanation:
We need to cast object of C1 to C2 class type. This can be done using C style casting or using
reinterpret cast.
6
Question 6
Consider the code segment below: [MSQ, Marks 2]
#include<iostream>
#include<exception>
using namespace std;
class Parent{
virtual void f(){}
};
int main(){
try{
Parent *pa = new Parent;
Parent *pb = new Child;
d) No Output
Answer: b)
Explanation:
We polymorphically cast pa to a pointer of Parent which is actually pointing to an object of
Parent type. However, the implicit downcasting is now allowed. Hence, c1 will be NULL. So,
it will print Bad Cast Parent. Rest of the castings are allowed.
7
Question 7
Consider the following code segment. [MCQ, Marks 2]
#include<iostream>
#include<exception>
using namespace std;
class Parent{
void f(){}
};
int main(){
try{
Parent *pa = new Parent;
Parent *pb = new Child;
}
catch(exception &e){
cout << e.what();
}
return 0;
}
Answer: d)
Explanation:
As there is no polymorphic inheritance between Parent and Child class, casting can be done
between two classes using static cast operator successfully. That is, c1 or c2 can not be NULL.
Hence the program generates the output Static cast Successful for Parent & Child.
8
Question 8
Consider the below classes. [MCQ, Mark 2]
a) 1
b) 2
c) 3
d) 4
Answer: d)
Explanation:
The presence of a virtual function (either explicitly declared or inherited from a base class)
makes the class polymorphic. For such classes we need a class-specific virtual function table
(VFT). All four classes, thus, will setup virtual function tables.
9
Question 9
Consider the following program. [MCQ, Marks 2]
#include<iostream>
using namespace std;
struct One{
void func(){ cout << "Struct"; }
};
int main(){
One t;
test(t);
return 0;
}
a) Struct
b) ⟨No Output⟩
Answer: d)
Explanation:
The function test() takes argument of type const One& and calls o.func() where o is a
constant object.
But, the function func() is not declared as const function in the structure definition. Hence,
calling the function func() with a constant object generates compilation error i.e. Passing
const One as this argument of func() discards qualifiers.
10
Programming Questions
Question 1
Consider the following program. Fill in the blanks at LINE-1 following appropriate instruction
(given in comment) and LINE-2, LINE-3, and LINE-4 with appropriate keywords such that it
would satisfy the given test cases. Marks: 3
#include <iostream>
using namespace std;
class A {
protected:
char i;
public:
A(char a): i(a) {}
void display(char x){
cout << x << " ";
}
// create abstract function fun()
______________________; //LINE-1
};
int main() {
char ch;
cin >> ch;
A *pt[3] = {new B(ch), new C(ch), new D(ch)};
for(int i = 0; i < 3; i++){
pt[i]->fun();
}
return 0;
}
11
Public 1
Input: a
Output: b c d
Public 2
Input: s
Output: t u v
Private
Input: w
Output: x y z
Answer:
LINE-1: virtual void fun() = 0
LINE-2: public A
LINE-3: public A
LINE-4: public A
Explanation:
The abstract function at LINE-1 must be filled by virtual void fun() = 0;.
Since the class B, C and D all inherit class A, the LINE-2, LINE-3, and LINE-4 must be filled
by public A.
12
Question 2
Consider the following code snippet. Fill in the blank at LINE-1 with appropriate initialization
list. Also fill in the blanks at LINE-2 and LINE-3 with appropriate header such that it matches
the given test cases. Marks: 3
#include<iostream>
using namespace std;
class String{
char *arr;
int n;
public:
String(int k) : ______________________{} //LINE-1
_______________{ //LINE-2
return arr[--n];
}
________________________{ //LINE-3
char t;
for(int j = 0; j < k; j++){
cin >> t;
this->arr[j] = t;
}
return *this;
}
};
int main(){
int k;
cin >> k;
String s(k);
s = k;
for(int i = 0; i < k; i++)
cout << static_cast<char>(s) << " ";
return 0;
}
Public 1
Input: 4 ajay
Output: y a j a
Public 2
Input: 3 ram
Output: m a r
Private
Input: 6 soumen
Output: n e m u o s
Answer:
13
LINE-1: n(k), arr(new char(n))
LINE-2: operator char()
LINE-3: String operator=(int &k)
Explanation:
The initialization of the data-members at LINE-1 can be done as:
n(k), arr(new char(k))
At LINE-2, we overload type-casting operator for the statement static cast<char>(s) as:
operator char()
At LINE-3, we overload operator= for the statement s = k; as:
String operator=(char& k)
14
Question 3
Consider the following program. Fill in the blank at LINE-1 with appropriate header. Fill
in the blanks at LINE-2 and LINE-3 with appropriate type-casting statements such that it
satisfies the given test cases. Marks: 3
#include<iostream>
using namespace std;
class A{
int a = 10;
public:
void display(){
cout << a << " ";
}
};
class B{
int b = 20;
public:
void display(){
cout << b;
}
_______________{ //LINE-1
b = b + x;
}
};
int main(){
A t1;
fun(t1);
return 0;
}
Public 1
Input: 4
Output: 10 14
Public 2
Input: 7
Output: 10 17
15
Private
Input: 5
Output: 10 15
Answer:
LINE-1: void operator=(int x)
LINE-2: const cast<A&>
LINE-3: reinterpret cast<B&>
Explanation:
As per the function fun(), we need to overload operator= for the class B at LINE-1. It can
be done as operator=(int x).
To call a non constant function using a const object reference, we need to cast the reference
to a non-const reference. So, LINE-2 will be filled as const cast<A&>.
Casting between two unrelated classes at LINE-3 can be done as reinterpret cast<B&>
16
Question 4
Consider the following program. Fill in the blank at LINE-1, LINE-2, LINE-3 following appro-
priate inheritance statements such that it satisfies the given test cases.
Marks: 3
#include <iostream>
using namespace std;
class C1 {
public:
C1(int x = 0) { cout << x << " "; }
void fun(int i){ cout << i << " "; }
};
class C2 : _________________ { // LINE-1 : Inherit from class C1
public:
C2(int x = 0) : C1(++x) { fun(x); }
};
class C3 : _________________ { // LINE-2 : Inherit from class C1
public:
C3(int x = 0) : C1(++x) { fun(x); }
};
class CC : _________________ { // LINE-3 : Inherit from class C2 and C3
public:
CC(int i = 0) : C2(i*2), C3(++i) { fun(i); }
};
int main() {
int i;
cin >> i;
CC obj(i);
return 0;
}
Public 1
Input: 5
Output: 0 6 12 6
Public 2
Input: 1
Output: 0 2 4 2
Private
Input: -5
Output: 0 -4 -8 -4
Answer:
LINE-1: virtual public C1
LINE-2: virtual public C1
LINE-3: public C3, public C2
17
Explanation:
From all the test-cases, we can see that the default constructor for the class C1 is called only
once. Hence, the classes C2 and C3 must have used virtual inheritance. So, the LINE-1 and
LINE-2 need to be filled by virtual public C1.
Class CC must inherit class C2 and class C3. From classes C2 and C3, class C3 is invoked before
class C2. Hence, the LINE-3 need to be filled by public C3, public C2.
18