Most Tricky C++ Interview Questions - Part 2

 


If you want  to move one step beyond the basic C++ questions and rock your dream interview, then I have brought an exquisite  list of the most tricky and interesting C++ interview questions that every enthusiast must know. This will surely help to enhance your skills and boost your confidence in this language.

Now, if you are a beginner in C++ ,you might want to first understand the basic concepts of C++ programming language and then jump right back to this article to understand the content better.

Note : This article is second part of the series - Most Tricky C++ Interview Questions.

So let's get started with our exquisite list of some tricky C++ interview questions that I bet you wont wanna miss.


1. What is Operator Overloading in C++ ?

Operator overloading is a concept in C++ which allows C/C++ operators to have user-defined meanings on user-defined types (classes). 
For example, we can overload '+' operator in a class like string so that we can concatenate two strings by just using '+'.
Without using operator overloading if we try to use '+' with strings, it gives error because '+' operator is not defined for strings by default.

To overload an operator, we use a special type of function : 'operator' function.

Here we show overloading of both binary('+')and unary('-' negation) operators

For example, let's define '+' for Complex numbers (which are of the form a + i * b);
We require to define Complex class with two attributes 'a' and 'b'.
To overload '+' for Complex class,  define 'operator' function inside Complex which takes a Complex object as parameter and returns a new Complex object after evaluating '+'.
To overload unary operator '-' for Complex class, define "operator" function inside Complex which does not take any parameter and returns a new Complex object evaluating '-'.

class Complex{
	int a,b;
	public:
		Complex(){
		}
		Complex(int a, int b){
			this->a = a;
			this->b = b; 
		}

		Complex operator + (Complex complex){			// Overloading binary '+' operator 
			Complex object;					               // the resultant object which stores result of '+'
			object.a = this->a + complex.a;
			object.b = this->b + complex.b;
			return object;
		}

		Complex operator - (){							// Overloading unary '-'negation operator 
			Complex object;							// the resultant object which stores result of '-'
			object.a = -a;
			object.b = -b;
			return object;
		}
};

int main(){
	Complex complex1(1,2),complex2(3,4);
	Complex complexNew;
	complexNew = complex1 + complex2;   		// this actually works as complexNew = complex1.operator+(complex2);
												// complex1 is the caller object and complex2 is passed as argument

	Complex negationObj = -complex1;    		// Overloading of unary negation operator
												// this actually works as negationObj = complex1.operator-();
}


2. How can you overload pre and post increment(or decrement) for the same class ?

Think about this for a second. How will you overload preincrement operator ?

Complex operator ++ (){							
	Complex object;							
	object.a = ++a;
	return object;
}

That's exactly how you will overload preincrement operator.
Now think the same for postincrement operator. Now you would feel that the function wiil look exactly the same for postincrement too. And that is true but the thing is if we want to overload both of them together how will it happen ? How to distinguish between both? Is it not possible?
The answer is that it is definitely possible to overload together. For that the preincrement operator will be overloaded exactly as shown above. Now postorder will be overloaded as :

Complex operator ++ (int unuse){							
	Complex object;							
	object.a = ++a;
	return object;
}

Just a small difference is that we take the operator function with an integer parameter and through this way compiler can distinguish between pre and post increment operator functions, although you don't need to actually pass that parameter. It is just a syntax norm to distinguish between pre and post increment .


3. What is friend function and friend class in C++ ?

A friend function in C++ is a function which can access the private and protected members of a class even though it is not a member of that class. But this access must be done through object of that class. A friend function can be : 
a. member of another class, 
b. a global function 
A friend function can be friend to more than one class at the same time. Friend function is declared using friend keyword. For example , Consider the code snippet below :

class Complex{
	int a,b;
	public:
		friend void frFunc(Complex complex); 		// declaring friend function
};

void frFunc(Complex complex){	
			cout<<complex.a<<" "<<complex.b<<endl;  // valid because frFunc function is friend to class Complex so 
            											 // it can access its private attributes a and b using object of Complex
}

Use case for friend function : You might be wondering why do we need a friend function, it somewhat lessens the value of encapsulation in OOPS. Yeah you are correct and extensive use of friend functions can be harmful. But in some situation it is very helpful to use a friend function. Consider this problem : You want to add the values of private attributes of two separate classes. How will you do it ? 

You might not be able to solve this unless you think about friend functions. In this case we can declare a function which is a friend to both the given classes and thus it can access private members of both these classes and thus perform addition

Now, second part of the same question, what is a friend class ?

 If we have a class A and we want all functions of this class to be able to access all the members of some other class B then one way is that declare each function of A to be friend to class B. But a better approach would be to declare class A to be friend to B. In this way all the functions of A are implicitly friends to B. Then A is referred to as friend class to B. For example :

class Complex{
	int a,b;
	public:
		friend class FriendClass 		// declaring friend class
};

class FriendClass{						

	void frFunc(Complex complex){		
		cout<<complex.a<<" "<<complex.b<<endl;																
	}	

	void frFunc2(Complex complex){
		cout<<complex.a+complex.b<<endl;
	}												
}

Since class FriendClass is friend to class Complex therefore both frFunc and frFunc2 are implicitly friends to Complex.


4. Why do we require initializer list in C++ if we already have constructors ? 

The initializer list is used to directly initialize data members of a class. It starts after the constructor name and its parameters. The list begins with a colon ( : ) and is followed by the list of variables that are to be initialized – all of​ the variables are separated by a comma with their values in curly brackets. For example : 

  class Complex{
	int a,b;
	Complex(int x, int y) : a(x), b(y)		// initializer list
	{ }
};

But this work can also be done with constructor, Then why use initializer list? 
Initializer list is required because : 
a. Const members cannot be initialized inside constructor. 
b. Reference variables can be initialized only once and need to be initialized only through initializer list. 
c. If a class inherits properties of another class then to call specific constructor of the base class, initializer list is mandatory. 
Let's check how the code looks for these cases :

class Base{
	int x;
	public:
		Base(int x){
		this->x=x;
		}
};

class Derived : public Base{
	int a,b;
	const int c;		//  const variable
	int &y;			// reference variable

	public:
		Derived(int x, int y, int &ref, int constant, int z) : c(constant), y(ref), Base(z)	
		{
			a=x;
			b=y;
		}
};  
  

Note carefully how Base class constructor is called above : Base(x). If we miss this , the code will give runtime error(while creating Derived object)  because in that case default constructor(Base() ) is considered to be called but a class does not have an implicit default constructor if it declares any explicit constructor(Base has one). Therefore Base has no default constructor. 


5. How can you stop someone from taking address of your object (security concern) ?


class Complex{
	int a,b;
};

int main(){	
	Complex complex;
	cout<<&complex;
}  
  

We can see how we can directly take address of the object complex using & operator.
We need to prevent this.
This can be prevented by Operator Overloading , which we have already discussed here.
We can overload '&' operator in Complex class and declare it to be private. Now we cannot take address of this class outside this class thus preventing any misuse.

Code snippet for this approach :

class Complex{
		private:
			int a,b;
			Complex * operator & (){
				return this;
			}
};

int main(){
	Complex complex;
	cout<<&Complex ;		// Complie time error as '&' is overoaded as private in Complex class.
}
  


This brings us to the end of Part-2 of this series. Also check out the other parts in the same series to find more challenging C++ interview questions :

Thank you for your patience reading. If you enjoyed this post, I’d be very grateful if you’d help it spread by emailing it to a friend, or sharing it on Whatsapp or Facebook. 

Happy learning!!