0% found this document useful (0 votes)
2 views10 pages

cpp_classes_notes

The document provides comprehensive lecture notes on C++ classes, covering key concepts such as classes, access specifiers, constructors, inheritance, polymorphism, encapsulation, abstraction, and more. It highlights the principles of object-oriented programming, including encapsulation, abstraction, inheritance, and polymorphism, which are essential for creating modular and maintainable code. Additionally, it discusses advanced topics like operator overloading, exception handling, and the differences between structures and classes.

Uploaded by

dkc26300
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views10 pages

cpp_classes_notes

The document provides comprehensive lecture notes on C++ classes, covering key concepts such as classes, access specifiers, constructors, inheritance, polymorphism, encapsulation, abstraction, and more. It highlights the principles of object-oriented programming, including encapsulation, abstraction, inheritance, and polymorphism, which are essential for creating modular and maintainable code. Additionally, it discusses advanced topics like operator overloading, exception handling, and the differences between structures and classes.

Uploaded by

dkc26300
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Classes in C++

Lecture Notes • Object-Oriented Programming

1. What is a Class?
A class is a user-defined data type that bundles data (variables) and functions (methods)
together into a single unit. It acts as a blueprint, while an object is an actual instance created
from that blueprint.

class Car {
public:
string brand;
int speed;

void drive() {
cout << brand << " is driving at "
<< speed << " km/h";
}
};

int main() {
Car c1; // object
[Link] = "Toyota";
[Link] = 80;
[Link]();
}

2. Access Specifiers
Access specifiers control which parts of a program can access the members of a class.

• private — accessible only inside the class (default for class members)
• public — accessible from anywhere the object is visible
• protected — accessible within the class and any derived (child) classes

3. Constructors & Destructors


A constructor is a special member function with the same name as the class. It runs
automatically when an object is created and has no return type. A destructor, written as
~ClassName(), runs automatically when an object is destroyed and is typically used for
cleanup (e.g. releasing memory).

class Point {
public:
int x, y;

Point(int a, int b) { // constructor


x = a;
y = b;
}

~Point() { // destructor
cout << "Destroyed";
}
};

Types of constructors:

• Default constructor — takes no arguments, e.g. Point()


• Parameterized constructor — takes arguments to initialize members, as shown above
• Copy constructor — creates a new object as a copy of an existing one
Point p1(3, 4);
Point p2 = p1; // copy constructor invoked

// User-defined copy constructor


Point(const Point &p) {
x = p.x;
y = p.y;
}

4. Inheritance
Inheritance allows one class (the derived class) to acquire the properties and behavior of
another class (the base class). It supports code reuse and models real-world “is-a”
relationships.

class Vehicle {
public:
int speed;
void show() {
cout << "Speed: " << speed;
}
};

class Car : public Vehicle { // Car inherits Vehicle


public:
string brand;
};

int main() {
Car c1;
[Link] = 100; // inherited member
[Link] = "Toyota";
[Link]();
}

• public inheritance — base's public/protected members keep their access level


• protected inheritance — public members of base become protected in derived
• private inheritance — public/protected members of base become private in derived
Types of inheritance: single, multiple, multilevel, hierarchical, and hybrid.
// Multilevel inheritance
class A { };
class B : public A { };
class C : public B { };

// Multiple inheritance
class X { };
class Y { };
class Z : public X, public Y { };

5. Polymorphism
Polymorphism means “many forms.” It allows the same function name or operator to behave
differently depending on context. C++ supports two kinds: compile-time (function/operator
overloading) and run-time (virtual functions).

// Compile-time polymorphism: function overloading


class Calculator {
public:
int add(int a, int b) { return a + b; }
double add(double a, double b) { return a + b; }
};

// Run-time polymorphism: virtual functions


class Animal {
public:
virtual void sound() { cout << "Some sound"; }
};

class Dog : public Animal {


public:
void sound() override { cout << "Bark"; }
};

int main() {
Animal* a = new Dog();
a->sound(); // outputs "Bark"
}

6. Encapsulation
Encapsulation is the bundling of data and the methods that operate on that data within one
unit, while restricting direct access to some of the object's components. It is usually achieved
by making data members private and providing public getter/setter functions.

class BankAccount {
private:
double balance;

public:
void deposit(double amount) {
if (amount > 0) balance += amount;
}
double getBalance() {
return balance;
}
};

Encapsulation protects data integrity by preventing external code from setting invalid values
directly.

7. Abstraction
Abstraction means exposing only essential features of an object while hiding the
implementation details. In C++ this is achieved using abstract classes (classes with at least
one pure virtual function) and interfaces.

class Shape {
public:
virtual double area() = 0; // pure virtual function
};

class Circle : public Shape {


private:
double radius;
public:
Circle(double r) { radius = r; }
double area() override {
return 3.1416 * radius * radius;
}
};

A class containing a pure virtual function cannot be instantiated directly; it must be inherited
and the function implemented by a derived class.

8. Static Members
A static data member is shared by all objects of a class rather than each object having its
own copy. A static member function can be called without creating an object and can only
access static members.

class Counter {
public:
static int count; // declaration

Counter() { count++; }

static int getCount() {


return count;
}
};

int Counter::count = 0; // definition outside class

int main() {
Counter c1, c2, c3;
cout << Counter::getCount(); // outputs 3
}

9. Friend Functions & the ‘this’ Pointer


A friend function is not a member of a class but is granted access to its private and
protected members. The this pointer is an implicit pointer available inside every non-static
member function, pointing to the object that invoked it.

class Box {
private:
int width;
public:
Box(int w) { width = w; }

friend void printWidth(Box b); // friend declaration

Box& setWidth(int w) {
this->width = w; // 'this' distinguishes member from parameter
return *this;
}
};

void printWidth(Box b) {
cout << "Width: " << [Link]; // direct access to private member
}

10. Operator Overloading


C++ allows most operators to be redefined for user-defined types, letting objects be used with
natural syntax such as + or ==.

class Complex {
public:
double real, imag;
Complex(double r, double i) : real(r), imag(i) {}

Complex operator+(const Complex &other) {


return Complex(real + [Link], imag + [Link]);
}
};

int main() {
Complex c1(2, 3), c2(4, 5);
Complex c3 = c1 + c2; // calls operator+
}

11. Composition (Has-A Relationship)


Composition models a “has-a” relationship by including an object of one class as a member
of another. It is often preferred over inheritance for code reuse when there is no true “is-a”
relationship.
class Engine {
public:
void start() { cout << "Engine started"; }
};

class Car {
private:
Engine engine; // Car "has-a" Engine
public:
void startCar() {
[Link]();
}
};

12. Class Templates


Templates let a class work with any data type without rewriting code, enabling generic
programming.

template <typename T>


class Box {
private:
T value;
public:
Box(T v) { value = v; }
T getValue() { return value; }
};

int main() {
Box<int> intBox(10);
Box<string> strBox("Hello");
cout << [Link]();
cout << [Link]();
}

13. Constructor Initialization Lists


Instead of assigning values inside the constructor body, members can be initialized directly in
an initialization list. This is required for const members, reference members, and members
without a default constructor, and is generally more efficient.

class Point {
private:
const int x;
const int y;
public:
Point(int a, int b) : x(a), y(b) {
// x and y are initialized before
// the constructor body runs
}
};
14. Const Member Functions
A member function marked const promises not to modify any data members of the object.
This allows the function to be called on const objects and communicates intent clearly.

class Rectangle {
private:
double width, height;
public:
Rectangle(double w, double h) : width(w), height(h) {}

double area() const { // does not modify members


return width * height;
}
};

int main() {
const Rectangle r(4, 5);
cout << [Link](); // allowed because area() is const
}

15. Virtual Destructors


When a base class pointer is used to delete a derived class object, the base class destructor
should be declared virtual. Otherwise only the base part of the object is destroyed,
causing a resource leak in the derived class.

class Base {
public:
virtual ~Base() {
cout << "Base destroyed";
}
};

class Derived : public Base {


public:
~Derived() {
cout << "Derived destroyed";
}
};

int main() {
Base* b = new Derived();
delete b; // calls both destructors correctly
}

16. Structures vs Classes


In C++, struct and class are almost identical — the only difference is the default access
level.

• struct members are public by default


• class members are private by default
• Both can have constructors, destructors, methods, and support inheritance
struct Point {
int x, y; // public by default
};

class Point2 {
int x, y; // private by default
};

17. Nested Classes


A class can be defined inside another class. This is useful when a helper class is only
meaningful in the context of its enclosing class.

class Outer {
public:
class Inner {
public:
void show() {
cout << "Inside Inner class";
}
};
};

int main() {
Outer::Inner obj;
[Link]();
}

18. Exception Handling with Classes


Custom exception classes are commonly created by inheriting from std::exception,
allowing meaningful error information to be thrown and caught in a type-safe way.

#include <exception>

class InsufficientFunds : public std::exception {


public:
const char* what() const noexcept override {
return "Insufficient balance";
}
};

class Account {
public:
void withdraw(double amt, double balance) {
if (amt > balance)
throw InsufficientFunds();
}
};
int main() {
try {
Account a;
[Link](500, 100);
} catch (const std::exception &e) {
cout << [Link]();
}
}

19. Arrays of Objects


Just like primitive types, classes can be used to create arrays of objects, where each element
is a separate instance of the class.

class Student {
public:
string name;
int roll;

void display() {
cout << roll << ": " << name;
}
};

int main() {
Student students[3];
students[0].name = "Deepak";
students[0].roll = 1;
students[0].display();
}

20. Summary
Key object-oriented pillars covered in these notes:

• Encapsulation — bundling data with methods, hiding internal state


• Abstraction — exposing only essential behavior via abstract classes
• Inheritance — reusing and extending behavior from a base class
• Polymorphism — one interface, multiple implementations
Together these four principles form the foundation of object-oriented programming in C++,
enabling code that is modular, reusable, and easier to maintain.

21. Object Slicing


When a derived class object is assigned to a base class object (by value, not by
pointer/reference), the extra derived-class data is “sliced off.” This is a common source of
subtle bugs when working with polymorphism.

class Base {
public:
int x = 1;
};

class Derived : public Base {


public:
int y = 2;
};

int main() {
Derived d;
Base b = d; // object slicing: b.y does not exist
cout << b.x; // only base part is copied
}

To avoid slicing when polymorphic behavior is needed, always use pointers or references to
the base class instead of passing/assigning by value.

End of Notes

You might also like