Assignment - 5 Solution
Assignment - 5 Solution
Total Marks : 25
Question 1
Consider the following code segment. [MCQ, Marks 1]
#include <iostream>
class Base {
protected:
int number;
static int counter;
public:
Base() {
number = ++counter;
cout << number << "-" << counter << ", ";
}
};
int Base::counter = 0;
1
int main() {
Derived2 dObj[2];
return 0;
}
a) 1, 2, 3
b) 1, 2, 3-3, 1, 2, 3-3,
c) 1, 2, 3-3, 4, 5, 6-6,
d) 1-1, 2, 3, 4-4, 5, 6,
Answer: d)
Explanation:
When we create an object, all the constructors of the class hierarchy get executed in top-down
order. Since we create 2 objects of Derived2 type. For the first object, class Base prints
1-1, class Derived1 prints 2 and class Derived2 prints 3. For the second object, class
Base prints 4-4, class Derived1 prints 5 and class Derived2 prints 6.
2
Question 2
Consider the following code segment. [MCQ, Marks 1]
#include <iostream>
class Alpha {
public:
Alpha() {
cout << "A ";
}
~Alpha() {
cout << "-A ";
}
};
~Beta() {
cout << "-B ";
}
};
public:
Gamma() {
cout << "C ";
}
~Gamma() {
cout << "-C ";
}
};
int main() {
Gamma g1;
return 0;
}
b) A A B C -C -A -A
3
c) A C -C -A
d) A A B C -C -B -A -A
Answer: d)
Explanation:
When an object of class Gamma is being instantiated, the constructor of class Alpha is called,
which will print ”A” first. Then the data member of class Gamma is created, which will again
call the constructor of class Alpha and print ”A”, then print ”B” from the constructor of class
Beta. Finally, ”C” is printed from the constructor of class Gamma. After the end of the main()
function, the reverse of the already printed sequence will be printed from the destructors of
the classes. So, the answer is (d).
4
Question 3
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class Vehicle {
public:
Vehicle() {
cout << "Vehicle created, ";
}
~Vehicle() {
cout << "Vehicle destroyed, ";
}
};
~Car() {
cout << "Car destroyed, ";
}
};
~Bike() {
cout << "Bike destroyed, ";
}
};
public:
SportsCar() {
cout << "SportsCar created, ";
}
~SportsCar() {
cout << "SportsCar destroyed, ";
}
};
5
int main() {
SportsCar sc;
return 0;
}
a) Vehicle created, Car created, Vehicle created, Bike created, SportsCar created,
SportsCar destroyed, Bike destroyed, Vehicle destroyed, Car destroyed, Vehicle
destroyed,
b) Vehicle created, Car created, SportsCar created, Vehicle created, Bike created,
Bike destroyed, Vehicle destroyed, SportsCar destroyed, Car destroyed, Vehicle
destroyed,
c) Vehicle created, Car created, SportsCar created, Bike created, Bike destroyed,
SportsCar destroyed, Car destroyed, Vehicle destroyed,
d) Vehicle created, Car created, SportsCar created, Bike created, Vehicle destroyed,
Car destroyed, SportsCar destroyed, Bike destroyed,
Answer: a)
Explanation:
A constructor of the derived class must first call the constructors of the base classes to construct
the base class instances of the derived class.
The destructor of the derived class must call the destructor of the base classes to destruct the
base class instances of the derived class.
Thus, to instantiate an object of class SportsCar, it first calls the constructor of class
Vehicle which prints Vehicle created. Then the constructor of class Car which prints
Car created. However, to create an object of SportsCar, an object of class Bike needs to
be instantiated. The creation of the Bike object first calls the constructor of class Vehicle
which prints Vehicle created, and then the constructor of class Bike which prints Bike
created. Finally, the constructor of SportsCar is called which prints SportsCar created.
Similarly, the invocation of the destructors takes place in the exact reverse order.
6
Question 4
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class Instrument {
public:
void play() {
cout << "Instrument::play()";
}
int main() {
Guitar g;
______________________; // LINE-1
return 0;
}
Choose the appropriate option to fill in the blank at LINE-1 such that the output of the code
becomes Instrument::play().
a) g.play()
b) Instrument::play()
c) g.Instrument::play()
d) Instrument::g.play()
Answer: c)
Explanation:
We can access a base class function using the scope resolution operator even if it is hidden by
a derived class function. Hence, c) is the correct option.
7
Question 5
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
int value = 5;
class Parent {
protected:
int value;
public:
Parent() : value(15) {}
~Parent() {}
};
public:
Child() : value(25) {}
~Child() {}
void display() {
cout << _____________________ ; // LINE-1
}
};
int main() {
Child c;
c.display();
return 0;
}
Choose the appropriate option(s) to fill in the blank at LINE-1 such that the output becomes
25 15 5
a) this->value << " " << Parent::value << " " << value
b) Child::value << " " << Parent::value << " " << value
c) value << " " << Parent::value << " " << ::value
d) Child::value << " " << Parent::value << " " << ::value
Answer: c), d)
Explanation:
Since value = 25 is in the scope of class Child which is also the local scope for the function
8
display(), value can be accessed by writing Child::value or just by value.
Since value = 15 is in the scope of class Parent, it can be accessed by writing Parent::value.
Since value = 5 is in the global scope, it can be accessed by writing ::value. So option c)
and d) both are correct.
9
Question 6
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
int globalVar = 5;
class MyClass {
int memberVar;
public:
MyClass(int memberVar_ = 0) : memberVar(++memberVar_) { // LINE-1
++globalVar;
}
~MyClass() {
memberVar = 0;
globalVar = 0;
}
void print() {
cout << "memberVar = " << memberVar << ", globalVar = " << globalVar << endl;
}
};
void test() {
MyClass obj;
obj.print();
}
int main() {
MyClass obj;
test();
obj.print();
return 0;
}
a) memberVar = 6, globalVar = 7
memberVar = 1, globalVar = 8
b) memberVar = 6, globalVar = 8
memberVar = 1, globalVar = 0
c) memberVar = 1, globalVar = 7
memberVar = 2, globalVar = 8
d) memberVar = 1, globalVar = 7
memberVar = 1, globalVar = 0
10
Answer: d)
Explanation:
The statement MyClass obj; in main(), calls the constructor at LINE-1 which makes memberVar
= 1 and globalVar = 6.
Then the statement MyClass obj; in test(), calls the constructor at LINE-1 which makes
memberVar = 1 and globalVar = 7.
Then the statement obj.print(); in test() prints memberVar = 1, globalVar = 7.
As the function test() returns, the destructor for the local object obj would be called, which
makes memberVar = 0 and globalVar = 0.
Finally, the statement obj.print(); in main() prints memberVar = 1, globalVar = 0.
11
Question 7
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class Vehicle {
private:
int reg_no;
string type;
public:
Vehicle(int reg_no_, string type_)
: reg_no(reg_no_), type(type_) {}
void showDetails() {
cout << reg_no << ":" << type << ":";
}
};
public:
Car(int owner_id_, string owner_name_, int reg_no_, string type_)
: owner_id(owner_id_),
owner_name(owner_name_),
Vehicle(reg_no_, type_) {}
void showDetails() {
Vehicle::showDetails(); // LINE-1
cout << owner_id << ":" << owner_name;
}
};
int main() {
Car* carObj = new Car(101, "Rahul", 12345, "Sedan");
display(carObj); // LINE-2
delete carObj;
return 0;
}
a) 12345:Sedan:
b) 12345:Sedan:101
12
d) compiler error at LINE-2: ‘display’ was not declared in this scope
Answer: d)
Explanation: Compilers will not convert a derived (Car) class object into a base (Vehicle)
class object if the inheritance relationship is private. As the display() function takes a
parameter of type class Vehicle* and we are passing a parameter of class Car object, it will
give a compilation error as inaccessible base.
13
Question 8
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class Base {
public:
Base() {}
~Base() {}
private:
Base(const Base& obj) {}
public:
Derived() {}
void print() {
cout << data << " ";
}
};
int main() {
Derived d1(30);
Derived d2(40);
d1 = d2;
d1.print();
d2.print();
return 0;
}
a) 40 30
b) 40 40
Answer: c)
Explanation: Since class Derived inherits class Base where the copy constructor and
14
assignment operator function are both private, it prevents the free copy constructor and free
assignment operator function from being added to the Derived class. As a result, when d1 =
d2; invokes the assignment operator function, the call fails.
15
Question 9
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class X {
public:
int x;
};
class Y : protected X {
public:
int y;
};
class Z : public Y {
public:
int z;
int main() {
Z zObj(10, 20, 30);
cout << zObj.x << " "; // LINE-2
cout << zObj.y << " "; // LINE-3
cout << zObj.z;
return 0;
}
a) 10 20 30
Answer: c)
Explanation:
The inheritance relationship between X and Y is protected. Thus, x becomes protected in
class Y. The inheritance relationship between Y and Z is public. Thus, y remains public in
class Y, but x remains protected in class Z. As a result, x in class Z becomes invisible to
the main() function. Hence, the correct answer is c).
16
Programming Questions
Question 1
Marks: 3
Consider the following program. Fill in the blanks as per the instructions given below:
• at LINE-1 with the appropriate initialization list to initialize the data members,
• at LINE-2 to call displayContact(), such that it will satisfy the given test cases.
#include<iostream>
using namespace std;
class Contact {
private:
int phone_number;
string email;
public:
Contact(int phone_number_, string email_) : phone_number(phone_number_),
email(email_){}
void displayContact(){
cout << "Phone: " << phone_number << endl;
cout << "Email: " << email << endl;
}
};
17
Public 1
Input:
101 9876543210
Alice [email protected]
Output:
ID: 101
Name: Alice
Phone: 9876543210
Email: [email protected]
Public 2
Input:
102 1234567890
Bob [email protected]
Output:
ID: 102
Name: Bob
Phone: 1234567890
Email: [email protected]
Private
Input:
103 1112223333
Charlie [email protected]
Output:
ID: 103
Name: Charlie
Phone: 1112223333
Email: [email protected]
Answer:
LINE-1: emp id(emp id ), emp name(emp name ), Contact(phone number , email )
LINE-2: using Contact::displayContact;
Explanation:
At LINE-1, the data members from Employee must be initialized as:
emp id(emp id ), emp name(emp name ), and the data members from Contact must be ini-
tialized as: Contact(phone number , email ) Although the function displayContact() is
public in Contact, it becomes private in Employee due to private inheritance. So displayContact()
becomes inaccessible using the Employee object. In order to call the displayContact() func-
tion using the Employee object, at LINE-2 we must add:
using Contact::displayContact;
18
Question 2
Marks: 3
Consider the following program. Fill in the blanks as per the instructions given below:
• at LINE-2 and LINE-4 with the appropriate initialization lists, such that it will satisfy
the given test cases.
#include <iostream>
class Appliance {
protected:
int power;
public:
Appliance(int p) : power(p) {}
public:
WashingMachine(int p, int ds) : __________ {} // LINE-2
public:
Refrigerator(int p, int c) : ___________{} // LINE-4
19
ostream& operator<<(ostream& os, const Refrigerator& r) {
os << "Power: " << r.power << "W, Capacity: " << r.capacity << "L" << endl;
return os;
}
int main() {
int a, b, c, d, e;
cin >> a >> b >> c >> d >> e;
Appliance appliance(a);
WashingMachine wm(b, c);
Refrigerator fridge(d, e);
cout << appliance << wm << fridge;
return 0;
}
Public 1
Input:
500 600 50 700 200
Output:
Power: 500W
Power: 600W, Drum size: 50L
Power: 700W, Capacity: 200L
Public 2
Input:
300 400 35 450 150
Output:
Power: 300W
Power: 400W, Drum size: 35L
Power: 450W, Capacity: 150L
Private
Input:
1000 850 60 950 250
Output:
Power: 1000W
Power: 850W, Drum size: 60L
Power: 950W, Capacity: 250L
Answer:
LINE-1: public Appliance
LINE-2: drum size(ds), Appliance(p)
LINE-3: public Appliance
LINE-4: Appliance(p), capacity(c)
Explanation:
Since WashingMachine and Refrigerator both inherit class Appliance, at LINE-1 and
LINE-3 the inheritance statement must be public Appliance.
20
At LINE-2, the initialization list must be:
drum size(ds), Appliance(p)
and at LINE-4, the initialization list must be:
Appliance(p), capacity(c)
21
Question 3
Marks: 3
Consider the following program. Fill in the blanks as per the instructions given below:
• at LINE-1, LINE-2 and LINE-3 with initialization list,
• at LINE-4, LINE-5 and LINE-6 with function definitions, such that it will satisfy the
given test cases.
#include<iostream>
using namespace std;
class X {
int x;
public:
X(int _x = 0);
int getSum();
};
class Y : public X {
int y;
public:
Y(int _x = 0, int _y = 0);
int getSum();
};
class Z : public Y {
int z;
public:
Z(int _x = 0, int _y = 0, int _z = 0);
int getSum();
};
int main(){
int a, b, c;
cin >> a >> b >> c;
X xObj(a);
Y yObj(a, b);
Z zObj(a, b, c);
cout << xObj.getSum() << ", " << yObj.getSum() << ", " << zObj.getSum();
return 0;
}
Public 1
Input: 10 20 30
22
Output: 10, 30, 60
Public 2
Input: 10 -10 10
Output: 10, 0, 10
Private
Input: 10 20 -10
Output: 10, 30, 20
Answer:
LINE-1: x( x)
LINE-2: X( x), y( y)
LINE-3: Y( x, y), z( z)
LINE-4: return x;
LINE-5: return X::getSum() + y;
LINE-6: return Y::getSum() + z;
Explanation:
The initialization lists at LINE-1, LINE-2 and LINE-3 are as follows:
LINE-1: x( x)
LINE-2: X( x), y( y)
LINE-3: Y( x, y), z( z)
The definition of the getSum() functions at LINE-4, LINE-5 and LINE-6 are as follows:
LINE-4: return x;
LINE-5: return X::getSum() + y;
LINE-6: return Y::getSum() + z;
23