C++ Operator Overloading Quiz
35 in-depth questions covering C++ operator overloading, including arithmetic operators, comparison operators, stream operators, assignment rules, and best practices — with 16 code examples to master operator design and pitfalls.
Question 1
What is operator overloading in C++?
Question 2
What is the syntax for overloading an operator in C++?
Question 3
What operators cannot be overloaded in C++?
Question 4
What is the difference between member and non-member operator overloading?
Question 5
What is the most important rule for implementing binary arithmetic operators?
#include <iostream>
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// Member operator+ - left operand is *this
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
void print() const {
std::cout << real << " + " << imag << "i" << std::endl;
}
};
int main() {
Complex a(1, 2), b(3, 4);
Complex c = a + b; // Calls a.operator+(b)
c.print(); // Should print: 4 + 6i
return 0;
}Question 6
What is the Rule of Three for operator overloading?
Question 7
What is the copy-and-swap idiom for assignment operators?
Question 8
What is the most common pitfall when overloading comparison operators?
#include <iostream>
#include <string>
class Person {
private:
std::string name;
int age;
public:
Person(std::string n, int a) : name(n), age(a) {}
// Only overload ==, not !=
bool operator==(const Person& other) const {
return name == other.name && age == other.age;
}
// Missing != operator - compiler won't generate it!
};
int main() {
Person p1("Alice", 30), p2("Bob", 25);
if (p1 != p2) { // ERROR: operator!= not defined
std::cout << "Different people" << std::endl;
}
return 0;
}Question 9
What is the correct way to implement operator<< for output streams?
#include <iostream>
#include <string>
class Person {
private:
std::string name;
int age;
public:
Person(std::string n, int a) : name(n), age(a) {}
// Friend function for << operator
friend std::ostream& operator<<(std::ostream& os, const Person& p) {
os << p.name << " (" << p.age << " years old)";
return os; // Return stream for chaining
}
};
int main() {
Person p("Alice", 30);
std::cout << p << std::endl; // Works like built-in types
return 0;
}Question 10
What is the correct way to implement operator>> for input streams?
Question 11
What is the most important consideration when overloading the assignment operator?
#include <iostream>
#include <string>
class String {
private:
std::string* data;
public:
String(const char* s = "") : data(new std::string(s)) {}
~String() { delete data; }
// Copy constructor
String(const String& other) : data(new std::string(*other.data)) {}
// Assignment operator - handle self-assignment!
String& operator=(const String& other) {
if (this != &other) { // Self-assignment check
delete data; // Free old resource
data = new std::string(*other.data); // Allocate new
}
return *this; // Return reference for chaining
}
void print() const { std::cout << *data << std::endl; }
};
int main() {
String s1("Hello"), s2("World");
s1 = s2; // Assignment
s1 = s1; // Self-assignment (should be safe)
s1.print();
return 0;
}Question 12
What is operator precedence and how does it affect overloading?
Question 13
What is the most common mistake when overloading increment/decrement operators?
#include <iostream>
class Counter {
private:
int value;
public:
Counter(int v = 0) : value(v) {}
// Prefix increment
Counter& operator++() {
++value;
return *this;
}
// Postfix increment - note dummy int parameter
Counter operator++(int) {
Counter temp = *this; // Save current value
++value; // Increment
return temp; // Return old value
}
int getValue() const { return value; }
};
int main() {
Counter c(5);
Counter d = c++; // Postfix: d gets 5, c becomes 6
Counter e = ++c; // Prefix: c becomes 7, e gets 7
std::cout << "c: " << c.getValue() << ", d: " << d.getValue()
<< ", e: " << e.getValue() << std::endl;
return 0;
}Question 14
What is the key difference between overloading [] and at() for container classes?
Question 15
What is the most important rule for overloading function call operator ()?
Question 16
What is the copy-and-swap idiom and why is it preferred for assignment?
#include <iostream>
#include <string>
#include <algorithm> // for std::swap
class Resource {
private:
std::string* data;
public:
Resource(const char* s = "") : data(new std::string(s)) {}
~Resource() { delete data; }
// Copy constructor
Resource(const Resource& other) : data(new std::string(*other.data)) {}
// Assignment using copy-and-swap
Resource& operator=(Resource other) { // Note: pass by value!
std::swap(data, other.data); // Swap resources
return *this; // other destructor cleans up old resource
}
void print() const { std::cout << *data << std::endl; }
};
int main() {
Resource r1("Hello"), r2("World");
r1 = r2; // Exception-safe assignment
r1.print();
return 0;
}Question 17
What is the most common pitfall when overloading arithmetic compound assignment operators?
Question 18
What is the correct way to handle commutativity in operator overloading?
#include <iostream>
class Complex {
private:
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
// Member operator+ for Complex + Complex
Complex operator+(const Complex& other) const {
return Complex(real + other.real, imag + other.imag);
}
// Non-member operator+ for double + Complex
friend Complex operator+(double d, const Complex& c) {
return Complex(d + c.real, c.imag);
}
void print() const {
std::cout << real << " + " << imag << "i" << std::endl;
}
};
int main() {
Complex c(1, 2);
Complex result1 = c + 5.0; // Uses member operator+
Complex result2 = 5.0 + c; // Uses friend operator+
result1.print(); // 6 + 2i
result2.print(); // 6 + 2i
return 0;
}Question 19
What is the most important consideration when overloading the subscript operator []?
Question 20
What is the relationship between operator overloading and implicit conversions?
Question 21
What is the most common mistake when overloading relational operators?
Question 22
What is the correct way to implement operator bool() for conditional contexts?
Question 23
What is the key consideration when overloading operators for template classes?
#include <iostream>
template<typename T>
class Wrapper {
private:
T value;
public:
Wrapper(T v) : value(v) {}
// Template operator+ - works for any T that supports +
template<typename U>
auto operator+(const Wrapper<U>& other) const {
return Wrapper<decltype(value + other.value)>(value + other.value);
}
T get() const { return value; }
};
int main() {
Wrapper<int> w1(5);
Wrapper<double> w2(3.14);
auto result = w1 + w2; // Wrapper<double>(8.14)
std::cout << result.get() << std::endl;
return 0;
}Question 24
What is the most important rule for overloading the dereference operator *?
Question 25
What is the relationship between operator overloading and the standard library?
Question 26
What is the most common performance pitfall in operator overloading?
Question 27
What is the correct way to handle operator overloading in inheritance hierarchies?
Question 28
What is the most important safety consideration when overloading the comma operator?
Question 29
What is the key difference between overloading -> and * for smart pointers?
Question 30
What is the most important rule for overloading type conversion operators?
Question 31
What is the relationship between operator overloading and move semantics?
Question 32
What is the most common mistake when overloading the address-of operator &?
Question 33
What is the correct way to implement operator new and operator delete?
Question 34
What is the most important principle for deciding when to overload operators?
Question 35
What is the fundamental guideline for operator overloading design?
