Assignment 8 Solution
Assignment 8 Solution
Total Marks : 27
March 7, 2023
Question 1
Consider the program given below. [MCQ, Marks 2]
#include<iostream>
b) int float
c) int ALL
1
Answer: c)
Explanation:
For call validate(0); it executes statement throw 0;, which throws int type exception. int
type exception will be handled within the function validate() and it prints int .
For call validate(1); it executes statement throw i * 1.00;, which throws double type
exception. double type exception will be handled in the main function (because validate()
cannot handle it) and it prints ALL . Due to the exception in main() the control comes out of
the try block.
2
Question 2
Consider the program given below. [MCQ, Marks 2]
#include<iostream>
namespace PrinterErrors{
class PrinterException {};
class NozzleException : public PrinterException{};
class CartridgeException : public PrinterException{};
class HeadException : public PrinterException{};
class Printer{
public:
static void print(int i = 0){
try{
if(i == 0)
throw NozzleException();
else if(i < 0)
throw CartridgeException();
else if (i > 0 && i < 10)
throw HeadException();
else
throw PrinterException();
}
catch(HeadException) { std::cout << "PrinterErrors::HeadException"; }
}
};
}
int main(){
try{
_____________________________; //LINE-1
}
catch(PrinterErrors::PrinterException) {
std::cout << "PrinterErrors::PrinterException";
}
catch(PrinterErrors::NozzleException) {
std::cout << "PrinterErrors::NozzleException";
}
catch(PrinterErrors::CartridgeException) {
std::cout << "PrinterErrors::CartridgeException";
}
return 0;
}
Identify the option/s to fill in the blank at LINE-1 such that output IS NOT
PrinterErrors::PrinterException.
a) PrinterErrors::Printer::print(-1)
b) PrinterErrors::Printer::print(0)
3
c) PrinterErrors::Printer::print(5)
d) PrinterErrors::Printer::print(10)
Answer: c)
Explanation:
For option c), it throws exception HeadException, which is handled by the catch block within
the function print(). Therefore, option c) will print PrinterErrors::HeadException.
For all other options, the exception thrown cannot be handled within the function print().
Since in function main(), the first catch block handles exception PrinterErrors::PrinterException
which is the base class of all exceptions handled by the rest of the catch blocks, all these excep-
tions are handled at the first catch block. Therefore, it prints PrinterErrors::PrinterException.
4
Question 3
Consider the following program. [MCQ, Marks 2]
#include<iostream>
int main(){
try{
for(int i = -1; i < 2; i++)
print(i);
}
catch(...) { std::cout << "Some other exception "; }
return 0;
}
c) PrinterException PrinterException
Answer: b)
Explanation:
For print(-1), the thrown exception type is NozzleException. Since within print() func-
tion, the first catch block handles the exception of type PrinterException that is base class of
NozzleException, the first catch block will handle it and the output will be PrinterException.
For print(0), the thrown exception type is CartridgeException*. Since it is not handled
within print() function, it will be forwarded to main() function. In main(), it will be handled
with printing Some other exception, and the control goes out of for loop.
5
Question 4
Consider the following program. [MCQ, Marks 2]
#include<iostream>
class PrinterException {
public:
virtual const char* what() const throw() {
return "PrinterException*";
}
};
class NozzleException : public PrinterException{
public:
virtual const char* what() const throw() {
return "NozzleException*";
}
};
class CartridgeException : public PrinterException{
public:
virtual const char* what() const throw() {
return "CartridgeException*";
}
};
int main(){
for(int i = -1; i < 2; i++)
print(i);
return 0;
}
c) NozzleException*
d) 7
Answer: a)
Explanation:
For call print(-1), the code within print() throws the exception of type NozzleException*,
6
which is handled by the first catch block. Therefore, the output is NozzleException*.
For call print(0), the code within print() throws the exception of type PrinterException*,
which is handled by the second catch block. Therefore, the output is PrinterException*.
For call print(1), the code within print() throws the exception of type CartridgeException*,
which is handled by the second catch block (because it handles a base type exception). However,
since what() is a virtual function, it will be executed from the subclass CartridgeException.
Therefore, the output is CartridgeException*.
7
Question 5
Consider the following code segment. [MSQ, Marks 2]
#include<iostream>
template<typename T>
int compare(T n1, T n2){
return n1 - n2;
}
int main(){
std::cout << _______________; //LINE-1
return 0;
}
Which of the following call/s to compare at LINE-1 will result in compiler error?
a) compare(’i’, ’k’)
b) compare(31.46, 34.0)
c) compare(31.46, 34)
d) compare(’A’, 34)
Answer: c), d)
Explanation:
Since the types of the actual arguments in the calls in option c) and d) are different, the
deduction of type T is ambiguous. Therefore, it generates a compiler error – ”no matching
function for call to compare”.
8
Question 6
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
_________________________________________________ //LINE-1
class Pair {
T1 n1;
T2 n2;
public:
Pair(T1 _n1, T2 _n2) : n1(_n1), n2(_n2) { }
void show() {
std::cout << n1 << " " << n2 << std::endl;
}
};
int main(){
Pair<> ob1(120, 88);
ob1.show();
Pair<> ob2('x', 'X');
ob2.show();
return 0;
}
Choose the appropriate option to fill in the blank at LINE-1 so that the output become:
120 X
120 X
Answer: d)
Explanation:
As the output given, the data member n1 should be of type int and n2 should be of type
char. Hence, the template should be defined as template<typename T1 = int, typename
T2 = char>.
9
Question 7
Consider the following program. [MCQ, Marks 2]
#include <iostream>
struct point{
point(int x = 0, int y = 0) : x_(x), y_(y){}
point(const point& p_) : x_(p_.x_), y_(p_.y_){}
void print() { std::cout << "[" << x_ << ", " << y_ << "]"; }
int x_, y_;
};
template<typename T>
class calculator{
public:
calculator(T val) : val_(val){}
T add(calculator c){
val_ += c.val_;
return val_;
}
private:
T val_;
};
___________________________ //LINE-1
__________________________ { //LINE-2
public:
calculator(point val) : val_(val) {}
point add(calculator c){
val_.x_ += c.val_.x_;
val_.y_ += c.val_.y_;
return val_;
}
private:
point val_;
};
int main() {
double d1 = 4.5, d2 = 3.35;
calculator<double> c1(d1);
calculator<double> c2(d2);
std::cout << c1.add(c2) << " ";
Choose the correct option to fill in the blanks at LINE-1 and LINE-2 so that the output becomes
10
7.85 [12, 23].
Answer: c)
Explanation:
class calculator is available in two versions. In the generic version and in a specialized
version for point. The template specialization at LINE-1 and the specialized class declaration
at LINE-2 can be done as:
LINE-1: template<>
LINE-2: class calculator<point>
11
Question 8
Consider the following code segment. [MCQ, Marks 2]
#include<iostream>
class Incrementor{
public:
Incrementor(int i = 0) : i_(i){}
________________ { return ++i_; } //LINE-1
________________ { return i_ = i_ + j; } //LINE-2
private:
int i_;
};
int main(){
Incrementor data(10);
std::cout << data(5) << " ";
std::cout << data();
return 0;
}
Choose the appropriate option to fill in the blank at LINE-1 and LINE-2 so that the output
becomes
15 16
Answer: c)
Explanation:
Since the statement data(5) in main() function calls function at LINE-2, it should an overload
of the function call operator with single argument and returns int.
Similarly, Since the statement data() in main() function calls function at LINE-1, it should
an overload of the function call operator with no arguments and returns int.
12
Question 9
Consider the following code segment. [MCQ, Marks 2]
#include <iostream>
class compute {
public:
int add(int a, int b) {
return a + b;
}
int subtract(int a, int b) {
return a - b;
}
};
____________________________________________________ { //LINE-1
return (obj->*fp)(x, y);
}
int main() {
compute cm;
std::cout << caller(10, 20, &cm, &compute::add) << " ";
std::cout << caller(10, 20, &cm, &compute::subtract) << std::endl;
return 0;
}
Choose the appropriate option to fill in the blank at LINE-1 so that the output becomes
30 -10
Answer: b)
Explanation:
The appropriate way to declare a function pointer to point to compute::add and compute::subtract
is as follows:
int(compute::*fp)(int, int))
Therefore, the correct option is b).
13
Programming Questions
Question 1
Consider the program below.
• Fill in the blank at LINE-1 with appropriate template definition for function average.
• Fill in the blank at LINE-2 with appropriate header for function average.
#include <iostream>
____________________________________ //LINE-1
__________________________________ { //LINE-2
_________________________ ; //LINE-3
for(int i = 0; i < N; i++)
total += arr[i];
avg = (double)total / N;
}
int main(){
______________ size = 5; //LINE-4
int iA[size];
for(int i = 0; i < size; i++)
std::cin >> iA[i];
double avg = 0.0;
average<int, double, 5>(iA, avg);
std::cout << avg;
return 0;
}
Public 1
Input: 10 20 30 40 50
Output: 30
Public 2
Input: -2 4 5 -1 7
Output: 2.6
Private
Input: 9 10 -5 7 11
Output: 6.4
Answer:
LINE-1: template<typename T1, typename T2, int N>
Or
14
LINE-1: template<class T1, class T2, int N>
LINE-2: void average(T1 arr[], T2& avg)
LINE-3: T1 total = 0
LINE-4: const int
Explanation:
Since the call to the function average is made as:
average<int, double, 5>(iA, avg); , the first two arguments of template are type argu-
ments, whereas the third one is non-type, which can be filled at LINE-1 as:
template<typename T1, typename T2, int N>
Or
template<class T1, class T2, int N>
At LINE-2, the function header can be
void average(T1 arr[], T2& avg)
At LINE-3, the declaration of total can be done as:
T1 total = 0; At LINE-4, the constant size can be declared as:
LINE-4: const int
15
Question 2
Consider the following program.
• Fill in the blank at LINE-2 with appropriate initializer list for the constructor.
• Fill in the blanks at LINE-3 with appropriate template definition of function print.
The program must satisfy the sample input and output. Marks: 3
#include<iostream>
________________________________ //LINE-1
class FiveVals{
type *base;
public:
FiveVals(type a[]) : ______________ { //LINE-2
for(int i = 0; i < N; i++)
base[i] = a[i];
}
void print();
};
________________________________ //LINE-3
_____________________ ::print(){ //LINE-4
for(int i = 0; i < N; i++)
std::cout << base[i] * 10 << "-";
}
int main(){
int a;
double b;
int c[5];
double d[5];
for(int i = 0; i < 5; i++){
std::cin >> a;
c[i] = a;
}
for(int i = 0; i < 5; i++){
std::cin >> b;
d[i] = b;
}
FiveVals<int, 5> iv(c);
iv.print();
FiveVals<double, 5> dv(d);
dv.print();
return 0;
}
16
Public 1
Input:
1 2 3 4 5
1.1 2.2 3.3 4.4 5.5
Output: 10-20-30-40-50-11-22-33-44-55-
Public 2
Input:
10 20 30 40 50
10.2 20.3 30.4 40.4 50.5
Output: 100-200-300-400-500-102-203-304-404-505-
Private
Input:
1 4 6 8 9
9.1 8.1 7.1 6.1 5.1
Output: 10-40-60-80-90-91-81-71-61-51-
Answer:
LINE-1: template<typename type, int N>
Or
LINE-1: template<class type, int N>
LINE-2: base(new type[N])
LINE-3: template<typename type, int N>
LINE-4: void FiveVals<type, N>
Explanation:
The template definition at LINE-1 must consists of a type parameter and a non-type parameter,
which can be done in any of the following ways:
template<typename type, int N>
Or
template<class type, int N>
At LINE-2, the initialization list can be specified as:
base(new type[N])
At LINE-3, the template definition for function print can be:
template<typename type, int N>
, and the function header can be:
void FiveVals<type, N>
17
Question 3
Consider the following program, in which add function has a generic version along with a
specialized version for complex type.
• Fill in the blank at LINE-1 to define the template for the generic version of add function.
• Fill in the blank at LINE-2 to define the template for the specialize version of add function.
• Fill in the blank at LINE-3 with the header of the specialize version of add function.
The program must satisfy the sample input and output. Marks: 3
#include<iostream>
class complex{
public:
complex(double r = 0.0, double i = 0.0) : r_(r), i_(i){}
int getR(){ return r_; }
int getI(){ return i_; }
friend std::ostream& operator<<(std::ostream& os, const complex& c);
private:
double r_, i_;
};
____________________ //LINE-1
T add(T n1, T n2){
return n1 + n2;
}
___________________ //LINE-2
______________________________ { //LINE-3
complex t(n1.getR() + n2.getR(), n1.getI() + n2.getI());
return t;
}
int main(){
double a, b, c, d;
int e, f;
std::cin >> a >> b >> c >> d >> e >> f;
complex c1(a, b);
complex c2(c, d);
std::cout << add<complex>(c1, c2) << ", ";
std::cout << add<int>(e, f);
return 0;
}
Public 1
Input: 10.4 4.5 2.5 2.5 10 20
Output: 12 + 6i, 30
18
Public 2
Input: 1 2 3 4 5 -4
Output: 4 + 6i, 1
Private
Input: 1.1 2.2 3.1 3.2 2 3
Output: 4 + 5i, 5
Answer:
LINE-1: template<class T>
LINE-2: template<>
LINE-3: complex add<complex>(complex n1, complex n2)
Explanation:
The template for the generic version of add can be defined as:
template<class T>
The template for the generic version of add and its header can be defined as:
template<>
complex add<complex>(complex n1, complex n2)
19