0% found this document useful (0 votes)
25 views16 pages

C++ 2024H1 Assignment-7

The document discusses an assignment for a C++ programming course. It contains 9 multiple choice questions testing concepts like type casting, virtual function tables, and operator overloading. It also includes one programming question asking the student to complete code implementing inheritance and operator overloading.

Uploaded by

sreeramvrkumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
25 views16 pages

C++ 2024H1 Assignment-7

The document discusses an assignment for a C++ programming course. It contains 9 multiple choice questions testing concepts like type casting, virtual function tables, and operator overloading. It also includes one programming question asking the student to complete code implementing inheritance and operator overloading.

Uploaded by

sreeramvrkumar
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 16

Programming in Modern C++: Assignment Week 7

Total Marks : 25

Partha Pratim Das


Department of Computer Science and Engineering
Indian Institute of Technology Kharagpur, Kharagpur – 721302
[email protected]

February 28, 2024

Question 1
Consider the following code segment. [MSQ, Marks 2]
#include <iostream>
using namespace std;
class student {
int roll ;
int marks;
public:
student(int _r, int _m) : roll(_r), marks(_m) {}
void update(int m) const{
(____________________)->marks = m; //LINE-1
}
void showInfo() const {
cout << roll << " : " << marks;
}
};
int main(void) {
const student s(3000, 56);
s.update(50);
s.showInfo();
return 0;
}
Fill in the blank at LINE-1 such that the program will print 3000 : 50.
a) const cast <student*> (this)

b) static cast <student*> (this)

c) dynamic cast <student*> (this)

d) (student*)(this)
Answer: a), d)
Explanation:
The statement const student s(3000, 56); defines s as a constant object. To modify its
data members, the constant-ness of the object needs to be removed. This can be done either
by const cast (in option a) or casting constant this pointer to student* type (in option d).

1
Question 2
Consider the following code segment. [MSQ, Marks 2]

#include <iostream>
using namespace std;
int main() {
char c = ’C’;
int d = 10;
char *cp = &c;
int *pd;
c = static_cast<char>(d); // LINE-1
d = static_cast<int>(c); // LINE-2
pd = static_cast<int*>(cp); // LINE-3
c = static_cast<char>(&c); // LINE-4
return 0;
}

Which line/s will give you an error?

a) LINE-1

b) LINE-2

c) LINE-3

d) LINE-4

Answer: c), d)
Explanation:
static cast cannot cast between two different pointer types. In LINE-3, int* is assigned to
char*. Hence it is an error.
Using static cast, it is not possible to change a pointer type to a value type. In LINE-4, char*
is assigned to char which is not possible using static cast.

2
Question 3
Consider the following code segment. [MSQ, Marks 2]

class Test1 { };
class Test2 : public Test1 { };
int main(){
Test1* t1 = new Test1;
Test2* t2 = new Test2;
t2 = __________________(t1);
return 0;
}

Fill in the blank at LINE-1 such that the program will be compiled successfully.

a) static cast<Test2*>

b) dynamic cast<Test2*>

c) reinterpret cast<Test2*>

d) const cast<Test2*>

Answer: a), c)
Explanation:
On each option, there is an attempt to cast from Test1* to Test2*. As we know, reinterpret cast
can be used to convert a pointer to an object of one type to a pointer to another object of
an unrelated type. Moreover, static cast is used to convert a base class object to a derived
class object. Hence option a) and c) are correct.

3
Question 4
Consider the following code segment. [MCQ, Marks 2]

class Test1 { };
class Test2 { };
Test1* t1 = new Test1;
Test2* t2 = new Test2;

Which of the following type-casting is permissible?

a) t2 = static cast<Test2*>(t1);

b) t2 = dynamic cast<Test2*>(t1);

c) t2 = reinterpret cast<Test2*>(t1);

d) t2 = const cast<Test2*>(t1);

Answer: c)
Explanation:
On each option, there is an attempt to cast from Test1* to Test2*, and these two classes are
unrelated. As we know, only reinterpret cast can be used to convert a pointer to an object
of one type to a pointer to another object of an unrelated type. Hence only option c) is correct.

4
Question 5
Consider the following code segment. [MCQ, Marks 2]

#include <iostream>
#include <typeinfo>
using namespace std;
class B { public: ~B(){}};
class D: public B {};
int main() {
B b;
D d;
D *dp = &d;
B *bp = dp;
D *dpp = (D*)dp;
cout << (typeid(bp).name() == typeid(dpp).name());
cout << (typeid(*bp).name() == typeid(*dpp).name());
cout << (typeid(dp).name() == typeid(dpp).name());
cout << (typeid(*dp).name() == typeid(*dpp).name());
return 0;
}

What will be the output?

a) 0101

b) 0111

c) 0110

d) 0011

Answer: d)
Explanation:
Type of bp is B* and type of dpp is D*. Thus, output is 0.
*bp and *dpp point to the same object d, and it is a static binding situation. Thus, both are
of type D and output is 0.
Type of dp and dpp is D*. Thus, output is 1.
*dp and *dpp point to the same object d, and it is a dynamic binding situation. Thus, both
are of type D and output is 1.

5
Question 6
Consider the following code segment. [MCQ, Marks 2]

#include <iostream>
using namespace std;
class A{ public: virtual ~A(){} };
class B : public A{};
class C : public A{};
int main(){
A objA;
B objB;
A* pA = dynamic_cast<A*>(&objB); //LINE-1
pA == NULL ? cout << "A" : cout << "B";
B* pB = dynamic_cast<B*>(pA); //LINE-2
pB == NULL ? cout << "A" : cout << "B";
C* pC = dynamic_cast<C*>(new A); //LINE-3
pC == NULL ? cout << "A" : cout << "B";
pC = dynamic_cast<C*>(&objB); //LINE-4
pC == NULL ? cout << "A" : cout << "B";
return 0;
}

What will be the output?

a) ABAB

b) BABA

c) BBAA

d) BABB

Answer: c)
Explanation:
The type-casting at LINE-1 is valid as it is an upper-casting. Hence, prints B.
At LINE-2, though it is a down-casting, it is allowed as the pointer pB points to the same type
of object (which of type B). Hence, prints B.
At LINE-3, the down-casting is invalid as the pointer pC points to parent type of object (which
is of type A). Hence prints A.
At LINE-4, the casting is also invalid as the pointer pC points to an object (which is of type
B) that is neither of its base type or derived type and hence prints A.

6
Question 7
Consider the following code segment. [MSQ, 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 VFT for the 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)

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:

7
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 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).
Also, I() will be in the VFT as B::I(B* const)

8
Question 8
Consider the following code segment. [MSQ, Marks 2]

#include <iostream>
using namespace std;
int main() {
const int i = 100;
const int *pi = &i;
int *qi = __________________(pi); //LINE-1
*qi = 200;
cout << *qi;
return 0;
}

Fill in the blank at LINE-1 so that the program will print ”200”.

a) const cast<int*>

b) static cast<int*>

c) dynamic cast<int*>

d) (int*)

Answer: a), d)
Explanation:
At LINE-1, pi of type const int* needs to be casted to int*. It can be accomplished by
const cast<int*>(pi) or (int*).

9
Question 9
Consider the code segment given below. [MCQ, Marks 2]

class Person {
public:
virtual void sleep() = 0;
virtual void work() {};
};
class Man: public Person {
public:
void sleep() {};
virtual void work() {};
};
class Woman: public Person{
public:
void sleep() {}
void work(){}
};
class Child{
public:
void play() {};
void cry() {};
};

How many virtual function table (VFT) will be created?

a) 1

b) 2

c) 3

d) 4

Answer: c)
Explanation:
All the classes Person, Man and Woman consist of some virtual functions. Thus, 3 virtual
function tables would be created.
The class Child does not have any virtual function. So no virtual function tables would be
created.

10
Programming Questions

Question 1
Complete the program with the following instructions.
• Fill in the blank at LINE-1 to complete operator overloading for assignment operator.
• Fill in the blanks at LINE-2 and LINE-3 to complete the type casting statements.
The program must satisfy the given test cases. Marks: 3
#include<iostream>
using namespace std;
class Test1{
int a = 10;
public:
void show(){
cout << a ;
}
_________________{ //LINE-1
a = a + x;
}
};
class Test2 : public Test1{
int b = 20;
public:
void show(){
cout << b << " ";
}
};
void fun(const Test2 &t, int x){
Test2 &u = _________________(t); //LINE-2
u.show();
Test1 &v = ___________________(u); //LINE-3
v = x;
v.show();
}
int main(){
Test2 t1;
int x;
cin >> x;
fun(t1, x);
return 0;
}

Public 1
Input: 4
Output: 20 14

Public 2
Input: 9
Output: 20 19

11
Private 1
Input: 15
Output: 20 25

Answer:
LINE-1: void operator=(int x)
LINE-2: const cast<Test2&>
LINE-3: reinterpret cast<Test1&>
Explanation:
As per the function fun(), we need to overload the operator equal to for the class Test1 at
LINE-1 so that the assignment v = x will be valid. It can be done as void operator=(int
x).
To call a non-constant function show() using a const object reference u, we need to cast the
reference to a non-const reference. So, LINE-2 will be filled as const cast<Test2&>.
Casting between two unrelated classes at LINE-3 can be done as reinterpret cast<Test1&>.

12
Question 2
Consider the following program with the following instructions.

• Fill in the blank at LINE-1 to complete constructor definition.

• Fill in the blank at LINE-2 to complete assignment operator overload function signature.

• Fill in the blank at LINE-3 to complete integer cast operator overload function signature.

The program must satisfy the sample input and output. Marks: 3

#include<iostream>
using namespace std;
class StringClass{
int *arr;
int n;
public:
StringClass(int k) : _________________________{} //LINE-1
_______________________{ //LINE-2
return arr[--n];
}
______________________________________(int &k){ //LINE-3
int t;
for(int j = 0; j < k; j++){
cin >> t;
this->arr[j] = t;
}
return *this;
}
};
int main(){
int k;
cin >> k;
StringClass str(k);
str = k;
for(int i = 0; i < k; i++)
cout << static_cast<int>(str) << " ";
return 0;
}

Public 1
Input: 3
1 3 5
Output: 5 3 1

Public 2
Input: 4
5 6 4 8
Output: 8 4 6 5

13
Private
Input: 6
1 2 3 4 5 7
Output: 7 5 4 3 2 1

Answer:
LINE-1: n(k), arr(new int(n))
LINE-2: operator int()
LINE-3: StringClass operator=
Explanation:
The initialization of the data-members at LINE-1 can be done as:
n(k), arr(new int(k))
At LINE-2, we overload type-casting operator for the statement static cast〈int〉(str) as:
operator int()
At LINE-3, we overload operator= for the statement str = k; as:
StringClass operator=(int& k)

14
Question 3
Consider the following program. Fill in the blanks as per the instructions given below:

• at LINE-1, LINE-2, LINE-3 and LINE-4 with appropriate inheritance statements

such that it will satisfy the given test cases. Marks: 3

#include<iostream>
using namespace std;
class B {
public:
B(int i) { cout << 50 * i << " "; }
B() { cout << 1 << " "; }
};
class D1 : ________________ { //LINE-1
public:
D1(int i);
};
class D2 : _________________ { //LINE-2
public:
D2(int i);
};
class D3 : __________________ { //LINE-3
public:
D3(int i);
};
class DD : ______________________________ { //LINE-4
public:
DD (int i) : D1(i), D2(i), D3(i) {
cout << 2 * i << " ";
}
};
D1::D1(int i) : B(i) {
cout << 5 * i << " ";
}
D2::D2(int i) : B(i) {
cout << 4 * i << " ";
}
D3::D3(int i) : B(i) {
cout << 3 * i << " ";
}
int main() {
int i = 0;
cin >> i;
DD dd(i);
return i;
}

Public 1
Input: 2
Output: 1 8 10 6 4

15
Public 2
Input: 3
Output: 1 12 15 9 6

Private
Input: 5
Output: 1 20 25 15 10

Answer:
LINE-1: virtual public B
LINE-2: virtual public B
LINE-3: virtual public B
LINE-4: public D2, public D1, public D3
Explanation:
If we observe the test-cases, the parametrized constructor is never called for the base class,
which implies all the derived classes have virtually inherited the base class. Therefore, the
blanks at LINE-1, LINE-2 and LINE-3 all have to be filled with: virtual public B The
order for invocation of the base class constructors depends on the order of inheritance. Again
from the test-cases it can be observed the sequence of inheritance at LINE-4 must be: public
D2, public D1, public D3

16

You might also like