Unit 4: Operator Overloading, Type Conversion and Inheritance
I. Object-Oriented Extension and Reuse
Object-oriented programming allows user-defined types to behave like built-in types and enables new classes to reuse or specialize existing classes. In C++, operator overloading defines operations on class objects, type conversion connects different representations, and inheritance establishes relationships between classes.
- Defining properties:
- Operator overloading: Assigns class-specific meaning to an existing C++ operator such as
+,-, or==. - Type conversion: Transforms a value from a basic type to a class type, or from a class type to a basic type.
- Inheritance: Creates a derived class from one or more base classes.
- Polymorphic behavior: Allows a derived class to replace or override inherited behavior.
- Object relationships: Inheritance represents an “is-a” relationship, while aggregation and composition represent “has-a” relationships.
- Operator overloading: Assigns class-specific meaning to an existing C++ operator such as
- Core conventions:
- Operators cannot be invented; only existing operators can be overloaded.
- Operator precedence, associativity, and number of operands cannot be changed.
- Constructors establish object state; destructors release resources.
- Access specifiers
private,protected, andpubliccontrol member visibility.
II. Operator Overloading — Class-Specific Operator Behavior
Operator overloading gives existing C++ operators a meaningful interpretation for operands of a user-defined class.
A. Unary operator overloading
Unary operator overloading defines an operator that acts on one operand, such as unary -, ++, --, or !.
- Member form: A unary member operator takes no explicit argument because the invoking object is the operand.
- Return value: Returning a new object suits operators such as unary minus; prefix increment commonly returns a reference.
- Postfix distinction: Postfix
++or--uses an unusedintparameter to distinguish it from the prefix form. - Concrete example:
class Number {
int value;
public:
Number(int v) : value(v) {}
Number operator-() const {
return Number(-value);
}
Number& operator++() { // Prefix ++
++value;
return *this;
}
Number operator++(int) { // Postfix ++
Number old = *this;
++value;
return old;
}
};- Meaning: If
ncontains5, then-nproduces an object containing-5;++nincrements before returning, whereasn++returns the previous value.
B. Binary operator overloading
Binary operator overloading defines an operation involving two operands, such as +, -, *, ==, or <.
- Member form: The left operand is the invoking object and the right operand is the single explicit parameter.
- Non-member form: Both operands are parameters; this supports symmetric conversions and is often declared
friendwhen private data must be accessed. - Result discipline: Arithmetic operators generally return a new object and should not modify their operands.
- Concrete example:
class Complex {
double real, imag;
public:
Complex(double r = 0, double i = 0) : real(r), imag(i) {}
Complex operator+(const Complex& rhs) const {
return Complex(real + rhs.real, imag + rhs.imag);
}
};- Operation: For
a = (2, 3)andb = (4, 1),a + breturns(6, 4). - Restrictions: Operators such as
.,.*,::,?:, andsizeofcannot be overloaded; at least one operand must be a user-defined type.
III. Type Conversion — Connecting Representations
Type conversion allows objects and fundamental values to cross class boundaries through constructors or conversion functions.
A. Basic type to class type conversion
Basic type to class type conversion constructs a class object from a fundamental value such as int, double, or char.
- Mechanism: A single-argument constructor acts as a converting constructor.
- Implicit conversion: Without
explicit, the compiler may invoke the constructor automatically during initialization or assignment. - Controlled conversion: The
explicitkeyword prevents unintended implicit conversions. - Concrete example:
class Distance {
double metres;
public:
explicit Distance(double m) : metres(m) {}
};
Distance d(12.5); // Direct conversion
Distance d2 = Distance(8.0); // Explicit construction- Interpretation: The basic value
12.5becomes themetresstate of aDistanceobject. - Design rule: Use
explicitwhen a basic value does not unambiguously represent the complete class object.
B. Class type to basic type conversion
Class type to basic type conversion extracts a fundamental representation from an object through a conversion function.
- Syntax: A conversion function is written as
operator type()and has no declared return type. - Conditions: It must be a non-static member function and takes no explicit parameters.
- Const correctness: Marking it
constpermits conversion of constant objects. - Concrete example:
class Distance {
double metres;
public:
Distance(double m) : metres(m) {}
explicit operator double() const {
return metres;
}
};
Distance d(7.5);
double m = static_cast<double>(d);- Result:
mreceives7.5. - Safety: An
explicitconversion operator requires a cast and avoids accidental use in unrelated arithmetic or Boolean contexts.
IV. Inheritance Structures — Forms of Class Derivation
A derived class inherits accessible members from a base class and may add data or behavior. These structures describe how classes are connected, independently of their access mode.
A. Derived class and base class
A base class provides existing state or behavior, while a derived class extends or specializes it.
- Base class: Declares reusable members, such as
Vehicle::start(). - Derived class: Inherits accessible members and adds specialized members, such as
Car::openBoot(). - Declaration:
class Vehicle {
public:
void start() {}
};
class Car : public Vehicle {
public:
void openBoot() {}
};- Relationship: A
Caris aVehicle, so aCarobject can call bothstart()andopenBoot(). - Access boundary: Base-class
privatemembers exist inside the derived object but cannot be accessed directly by derived-class functions.
B. Simple inheritance
Simple inheritance occurs when one derived class inherits from exactly one base class.
- Structure:
Base -> Derived. - Purpose: It adds specialization without combining unrelated class interfaces.
- Example:
SavingsAccountmay inherit common account details fromAccount. - Benefit: Shared operations such as
deposit()remain in the base class, reducing duplication.
C. Multilevel inheritance
Multilevel inheritance forms a chain in which one derived class becomes the base class of another.
- Structure:
A -> B -> C. - Example:
LivingThing -> Animal -> Dog. - Propagation:
Dogreceives accessible members originating in bothAnimalandLivingThing. - Construction order: Constructors run from the highest base to the most-derived class:
LivingThing, thenAnimal, thenDog. - Risk: Deep inheritance chains can make behavior and member ownership difficult to trace.
D. Multiple inheritance
Multiple inheritance allows one derived class to inherit directly from two or more base classes.
- Structure:
class C : public A, public B. - Example: A
SmartPrintermay inherit from bothPrinterandScanner. - Benefit: The derived class combines distinct interfaces or capabilities.
- Risk: Equal member names in different bases cause ambiguity, and repeated inheritance from a common ancestor creates duplicate base subobjects.
E. Hierarchical inheritance
Hierarchical inheritance creates several derived classes from one common base class.
- Structure: One base class branches into multiple derived classes.
- Example:
Shapemay be the base ofCircle,Rectangle, andTriangle. - Reuse: Common data or functions, such as
colourordraw(), are declared once inShape. - Specialization: Each derived class supplies behavior appropriate to its own geometry.
V. Inheritance Access Modes — Controlling Visibility
The inheritance mode determines how the base class’s public and protected members are treated inside the derived class; base private members remain directly inaccessible.
A. Private inheritance
Private inheritance transforms inherited public and protected members into private members of the derived class.
- Syntax:
class D : private B. - Client access: Outside code cannot use the inherited public interface through a
Dobject. - Further derivation: Classes derived from
Dcannot directly access those inherited members. - Use: It expresses implementation reuse rather than a public “is-a” relationship.
- Default: Inheritance is private when a C++
classomits the inheritance specifier.
B. Protected inheritance
Protected inheritance transforms inherited public and protected members into protected members of the derived class.
- Syntax:
class D : protected B. - Client access: Outside code cannot directly call inherited members through
D. - Further derivation: Subclasses of
Dmay access those inherited members. - Use: It shares implementation through an inheritance hierarchy without exposing the base interface publicly.
C. Public inheritance
Public inheritance preserves base public members as public and base protected members as protected.
- Syntax:
class D : public B. - Substitutability: A
Dobject can normally be used where aBobject is expected. - Interface preservation: Public base operations remain available to clients of the derived object.
- Use: It is the standard mode for modeling a genuine “is-a” relationship.
- Default: Inheritance is public when a C++
structomits the inheritance specifier.
VI. Inherited Behavior and Object Lifetime — Runtime and Structural Rules
Inheritance affects function selection, initialization, destruction, and member lookup throughout the class hierarchy.
A. Overriding member functions
Overriding occurs when a derived class supplies a function matching a virtual function declared in its base class.
- Requirements: The function name, parameter types, and
constqualification must match; compatible covariant returns are allowed for pointers or references. - Dynamic dispatch: Calls through a base pointer or reference invoke the derived implementation when the base function is
virtual. - Verification: The
overridespecifier makes the compiler reject accidental mismatches. - Concrete example:
class Shape {
public:
virtual void draw() const {}
virtual ~Shape() = default;
};
class Circle : public Shape {
public:
void draw() const override {}
};- Distinction: A same-named function with different parameters hides base overloads rather than overriding them.
B. Order of execution of constructors and destructors
Construction proceeds from base subobjects to the derived object, while destruction occurs in the exact reverse order.
- Construction sequence:
- Virtual base constructors execute first.
- Direct base constructors execute in declaration order.
- Data members execute in their declaration order.
- The derived constructor body executes last.
- Destruction sequence:
- The derived destructor body executes first.
- Data members are destroyed in reverse declaration order.
- Direct and virtual bases are destroyed afterward.
- Multiple inheritance: Base construction follows the order in the class declaration, not the initializer-list order.
- Polymorphic deletion: A base class used polymorphically needs a virtual destructor so deleting through a base pointer destroys the complete derived object.
C. Resolving ambiguities in inheritance
Ambiguity occurs when the compiler finds more than one eligible inherited member or more than one path to a base subobject.
- Scope resolution: Qualify the intended base explicitly, such as
obj.Printer::start(). - Derived wrapper: Define a derived member that deliberately selects or combines base implementations.
- Using declaration:
using Base::function;can expose a chosen overload set. - Diamond ambiguity: If
BandCboth inheritA, then a class inheriting both may contain twoAsubobjects. - Resolution choice: Ordinary qualification resolves member-name ambiguity; virtual inheritance resolves duplicated common-base state.
D. Virtual base class
A virtual base class ensures that the most-derived object contains only one shared subobject of a common base in a diamond hierarchy.
- Declaration:
class Person {};
class Student : virtual public Person {};
class Employee : virtual public Person {};
class TeachingAssistant : public Student, public Employee {};- Effect:
TeachingAssistantcontains onePersonsubobject rather than separateStudent::PersonandEmployee::Personsubobjects. - Initialization: The most-derived class,
TeachingAssistant, is responsible for constructing the virtual base. - Trade-off: Virtual inheritance removes duplicated state but introduces more complex object layout and initialization rules.
VII. Whole-Part Relationships — Object Ownership
Aggregation and composition model objects that contain or refer to other objects instead of inheriting their interfaces.
A. Aggregation
Aggregation is a weak “has-a” relationship in which the contained object can exist independently of the owner.
- Lifetime: Destroying the whole does not necessarily destroy the part.
- Representation: It is commonly implemented with references or non-owning pointers.
- Example: A
DepartmentaggregatesProfessorobjects that may exist before or after that department. - Ownership rule: The aggregating class must not delete externally owned objects unless ownership is explicitly transferred.
- Meaning: Aggregation models association and grouping, not substitutability.
B. Composition
Composition is a strong “has-a” relationship in which the part’s lifetime is controlled by the containing object.
- Lifetime: Member objects are constructed with the whole and destroyed automatically with it.
- Representation: It is commonly implemented through direct data members or owning smart pointers.
- Example:
class Engine {};
class Car {
Engine engine; // Constructed and destroyed with Car
};- Construction:
Engineis constructed before theCarconstructor body executes. - Destruction:
Engineis destroyed after theCardestructor body, during member destruction. - Contrast: Aggregation links independent objects; composition makes the part an owned component of the whole.
Did this save you a night before the exam?
LPU Notes is free, and it stays free. Ads cover part of the server bill. The rest comes out of a student's own pocket: the domain, the storage, and keeping the site up through the weeks everyone needs it at once.
The payment button didn't load. An ad blocker or a filtered network is the usual reason. to try again.
Nothing here is ever locked, and nothing unlocks. Chip in only if it was worth it. What it pays for →