C++ is a compelling and efficient programming language incorporating various capabilities, however, one major feature of C++ will be object-oriented programming. Object-oriented programming is a conceptual paradigm involving the usage of “objects” to represent data and functions within software programs, and these objects are instances of “classes.”
Classes essentially refer to the abstract data types supporting the building and behaviour of objects; they form the basis of object-oriented programming in C++. This is primarily because it reduces the redundancy of code in a program and, consequently, the time taken to find errors and debug them. In this article, we’ll learn about the classes and objects in C++ covering everything in detail with the syntax, examples, pros and cons, code examples, and much more.
What is Object-Oriented Programming (OOP)
C++ is one of the most popular programming languages that support object-oriented programming (OOP). Object-Oriented Programming (OOP) means modelling real-world entities as objects where each object is an instance of a class. In other words, object-oriented programming is a method for simulating tangible, real-world objects like vehicles and the relationships between them, such as those between students and teachers, etc. OOP models real-world entities as software objects with data associated with them and operational capabilities.
Key Concepts of OOP:
Encapsulation: The class and the included data (attributes), and methods (functions) that operate on that data are bundled together.
Inheritance: It is about new classes with attributes and methods from existing classes, enhancing code reusability.
Polymorphism: It is the ability to allow objects of different classes to be treated as objects from a common superclass. It is achieved through method overriding.
Abstraction: Hiding the internal implementation details and exposing only the essential functionalities.
Get curriculum highlights, career paths, industry insights and accelerate your technology journey.
Download brochure
What are Classes in C++?
In C++, a class is a user-defined data type that acts as an object creation template. It contains functions that manipulate the data (in the form of member functions) as well as the data itself (in the form of member variables). To use a class, simply declare an instance of it, which in C++ is equivalent to an object.
In the real world, we encounter cars of different makes and models, but they always have certain traits, such as colour, model, and year. Therefore, we may construct a single class with common car attributes rather than creating distinct classes for each type of car. Thus, classes are used to generate objects with comparable features by acting as a user-defined data type.
Declaring and Defining Classes
A class is declared using the keyword class, followed by the class name and a body enclosed in curly braces. The block starts with access specifiers followed by data members and member functions. This structure can include member variables (data) and member functions (methods).
Syntax:
class ClassName {
public:
// Member variables
// Member functions
};
Here,
ClassName is the name of the class.
public, private, and protected are access specifiers (more on this later).
What are Objects in C++?
An instance of a class is called an object. A class can be used to produce many objects after it is defined. Each object has its copy of the member variables but shares the same member functions. A data structure that is an instance of a class is called an object. Thus, memory is not allocated when a class is created. Rather, memory is allocated to store data and execute necessary operations on an instance when an object is declared and an instance is created.
Declaring Objects
We can declare objects to use the data and its member function. Declaring objects involves using the class name and then the name of the user-defined object.
Syntax:
ClassName obj; // creating an object of ClassName
Now that we have understood the class and object declaration and definition in C++, let’s see an example to learn more about how they are used in real-life examples.
Example:
#include <iostream>
using namespace std;
// Class definition
class Vehicle {
private:
// Private data members
string name;
int year;
float mileage;
public:
// Setter function to assign details to the vehicle
void setDetails(string name, int year, float mileage) {
// Using 'this' pointer to refer to the class's data members
this->name = name; // Assign parameter 'name' to the class member 'name'
this->year = year; // Assign parameter 'year' to the class member 'year'
this->mileage = mileage; // Assign parameter 'mileage' to the class member 'mileage'
}
// Function to display vehicle details
void showDetails() {
cout << "Name: " << name << endl; // Output the vehicle name
cout << "Year: " << year << endl; // Output the manufacturing year
cout << "Mileage: " << mileage << " km/l" << endl; // Output the mileage
}
};
int main() {
Vehicle c1; // Creating an object of the Vehicle class
// Setting the details of the vehicle using setDetails() method
c1.setDetails("BMW M4", 2024, 14.8);
// Displaying the details of the vehicle using showDetails() method
c1.showDetails();
return 0;
}
Output:
Name: BMW M4
Year: 2024
Mileage: 14.8 km/l
Explanation:
In this example, we define a class named Vehicle that represents a vehicle with three private attributes: name, year, and mileage. These attributes store the vehicle’s name, manufacturing year, and mileage, respectively.
To manage and update these attributes, we provide a public method called setDetails(), which takes the vehicle’s name, year, and mileage as arguments.
We also provide another public method, showDetails(), which displays the vehicle’s details by printing the values of the class’s private attributes.
Finally, the showDetails() method is called to display these details, resulting in the name, year, and mileage being printed as the output.
Access Modifiers
Access Modifiers in C++ classes allow us to manage who can access which members of the class. These are the keywords that are provided in the class and, under that access specifier, all members of the class will have a specific level of access. They are also referred to as access specifiers. They set restrictions on who can access class members from the outside and within. There are 3 different types of access modifiers in C++:
Public
Private
Protected
Public
Public members are accessible from outside the class. Any function, whether inside or outside the class, can directly access public members.
Syntax:
class MyClass {
public:
int myNumber; // Public Member
void myFunction() { // Public method
…
}
};
Private
Access to private members is limited to the class. They are not directly accessible from outside of the class. Members are private by default if no access modifier is given.
Syntax:
class MyClass {
private:
int mySecretNumber; // Private Member
void mySecretFunction() { // Private method
…
}
};
Protected
Protected members are similar to private members, but they can also be accessed by derived classes (child classes) in addition to the class in which they are declared. They are often used in inheritance when you want to allow derived classes to access certain properties or methods.
Syntax:
class MyClass {
protected:
int protectedVar; // Protected member
};
Access Modifiers in C++
Access Modifier
Within Class
Derived Class
Outside the Class (main)
Public
Yes
Yes
Yes
Private
Yes
No
No
Protected
Yes
Yes
No
Constructors and Destructors
Constructors
A constructor is a special function of a particular class that is called automatically during the creation of an object of that class. Most importantly, it is used to initialise objects. Class and the constructors have the same names, and constructors do not return anything, not even void. Simply put, constructors are called whenever an object of a class is created.
Types of Constructors:
Default Constructor: A constructor with no parameters. If you don’t define any constructor in your class, the compiler provides a default constructor automatically.
Parameterised Constructor: A constructor that takes one or more parameters is a parameterised constructor. It allows you to initialise data members with specific values when creating an object.
Copy Constructor: A constructor that initialises an object using another object of the same class. It is used to create a copy of an existing object.
#include <iostream>
using namespace std;
// Class definition
class Car {
public:
string brand;
int year;
// Create a constructor for the Car class
Car(string b, int y) {
brand = b;
year = y;
}
// Show the car information
void displayInfo() {
cout << "Brand: " << brand << endl;
cout << "Year: " << year << endl;
}
};
int main() {
Car myCar("BMW", 2021); // using the constructor
myCar.displayInfo(); // accessing the function to display information
return 0;
}
Output:
Brand: BMW
Year: 2021
Destructors
A destructor is a member function that is invoked when an object is destroyed. It is implemented to free unused resources such as memory allocation, which is associated with the life of the object. Destructor is a member function that is named in the same manner as the class but has a tilde (~) symbol before it. The class could have only one destructor and it’s automatic when its scope of the object is finished.
Syntax:
~ClassName() {
// Destructor code
}
Example:
#include <iostream>
using namespace std;
// Class definition
class Car {
public:
string brand;
int year;
// Constructor
Car(string b, int y) {
brand = b;
year = y;
cout << "The car constructor called for " << brand << endl;
}
// Destructor
~Car() {
cout << "The car destructor called for " << brand << endl;
}
// Show the car information
void displayInfo() {
cout << "Brand: " << brand << endl;
cout << "Year: " << year << endl;
}
};
int main() {
Car myCar("BMW", 2024); // Using the constructor
myCar.displayInfo(); // Accessing the function to display information
return 0;
}
Output:
The car constructor called for BMW
Brand: BMW
Year: 2024
The car destructor called for BMW
Member Functions in Classes
Member functions in classes are used to access or modify the members of that class and can be defined inside the class or outside using the scope resolution operator (::).
Inside Class definition
Member functions can be defined inside a class directly without declaring it first in class. Below is an example to define the member function inside the class in C++.
Example:
class Circle {
public:
float radius;
float area() {
return 3.14 * radius * radius;
}
};
Outside Class definition
Member functions can be defined outside a class by first declaring it inside the class and then defining it outside the class. Below is an example to define the member function outside the class in C++.
A class can be accessed in different ways in C++ depending on its access specifier (public, private, or protected), member functions (methods), and data members (attributes or fields).
Data Members and Member Functions Access:
External users can access public members.
Only from within the class or by utilising unique functions like getter and setter methods can one access private members.
Access to protected members is restricted to friends, derived classes, and the class itself.
Example:
#include <iostream>
using namespace std;
class Car {
private:
string model;
int year;
public:
// Setter functions to set private members
void setModel(string m) {
model = m;
}
void setYear(int y) {
year = y;
}
// Getter functions to access private members
string getModel() {
return model;
}
int getYear() {
return year;
}
// Public function that can be called directly
void showDetails() {
cout << "Model: " << model << ", Year: " << year << endl;
}
};
int main() {
Car myCar;
// Accessing private members through public methods
myCar.setModel("BMW M5 Sport");
myCar.setYear(2023);
// Accessing public member function
myCar.showDetails();
// Accessing private members using getter methods
cout << "The car model is: " << myCar.getModel() << endl;
cout << "The car year is: " << myCar.getYear() << endl;
return 0;
}
Output:
Model: BMW M5 Sport, Year: 2023
The car model is: BMW M5 Sport
The car year is: 2023
Explanation:
In this example, the data members such as model and year are private, so they can’t be accessed directly from outside the class.
To change the private members, we utilise the public setter procedures setModel() and setYear().
The getModel() and getYear() public getter procedures are used to retrieve members of the private data.
The information about the car is immediately printed via the public member function displayCarDetails().
Static Members and Functions
Static members are shared among all objects of a class in C++ and are declared using the `static` keyword.
Example:
#include <iostream>
using namespace std;
class Car {
private:
string model;
int year;
static int carCount; // static data member
public:
// Constructor
Car(string n, int i) : model(n), year(i) {
carCount++; // Increment car count for every new object
}
// Static member function
static int getCarCount() {
return carCount;
}
// Public function that can be called directly
void showDetails() {
cout << "Model: " << model << ", Year: " << year << endl;
}
};
// Initialise the static data member outside the class
int Car::carCount = 0;
int main() {
Car c1("BMW", 2010);
Car c2("Audi", 2023);
c1.showDetails();
c2.showDetails();
// Accessing static member function using class name
cout << "Total Cars: " << Car::getCarCount() << endl;
return 0;
}
In this example, the carCount variable is a static data member, so it is shared among all objects of the Car class.
The static member function getCarCount() can access this static data member.
Static members are accessed using the class name, like Car::getCarCount() since they are not tied to any specific object.
Array Of Objects In C++
An array of objects maintains many instances of a class, although it differs from an array of raw data types (such as int or float). When working with several items that have the same structure, like a list of students, goods, or books, an array of objects is useful.
Example:
#include <iostream>
using namespace std;
class Car {
private:
string model;
int year;
public:
// Constructor to initialise Car details
Car(string n = "", int r = 2023) : model(n), year(r) {}
// Function to display car details
void showDetails() {
cout << "Name: " << model << ", Year: " << year << endl;
}
};
int main() {
// Creating an array of Car objects
Car cars[3] = {
Car("BMW", 2023),
Car("Mercedes", 2024),
Car("Audi", 2020)
};
// Accessing elements in the array
for (int i = 0; i < 3; i++) {
cars[i].showDetails();
}
return 0;
}
In this example, three Car class objects are stored in an array called cars.
The model and year of each car are initialised by the constructor.
For every object in an array, the showDetails() method is called via a loop.
Difference Between a Class and Structure in C++
Criteria
Class
Structure
Access Specifier
By default, members are public.
By default, members are private.
Inheritance
Classes support inheritance (base and derived classes).
Structures in C++ do not support inheritance.
Member functions
A class can have member functions (methods).
A structure can have member functions.
Memory Allocation
Class instances i.e., objects have memory for methods too.
Structures allocate memory for each data member separately.
Usage
Classes are used to represent complex data with methods.
They are used for lightweight data grouping (like C-style structs).
Constructors
A class can have constructors with the same name.
Structures do support constructors.
Destructors
A class can have destructors with the same name.
Structures do support destructors.
Object-Oriented Paradigm
Fully supports object-oriented programming.
Not fully object-oriented.
Null values
A Class can contain null values.
A structure cannot contain null values. However, they may have pointers set to NULL.
Real-World Applications of Classes and Objects
Banking Systems: The transformation of the existing system into a system is a normal practice in any organisation. One system that is very common in utilisation for most organisations and other businesses is the use of class constructs and their behaviours in different scenarios. Most of those transactions are computerised with the existing interface usually called a banking system. The BankAccount class provides fields that have balance, account number and account type, and operations such as deposit, withdrawal, and transfer.
E-commerce: Systems such as Amazon, eBay, and Flipkart can use classes and objects to model users, products, orders, shopping carts, and so on. A Product class can maintain a representative model of individual products with a collection of their attributes such as a name, price, and stock however Users may have some methods like addToCart() and purchase() to these products.
Game Development: In the field of game design, the classes and objects are paramount to elaborate models that navigate the pixels, weapons, and even vehicles and the game habitat in general. When you design a character in a role-playing game, for instance, the Character class will define for the player his health, strength, and skills among others. Accordingly, the Weapon class will also consist of different weapons that the character can hold.
Healthcare: The classes and objects can be used in any other sector for example, in healthcare management systems patients, doctors, medical records, appointments, billing systems, etc.
Education Systems: Educational institutions can represent students, teachers, courses, and grades with classes and objects.
Objects as Function Arguments
In C++, objects can be passed as arguments to functions in three ways:
Pass-by-value
Pass-by-reference
Pass-by-pointer
Pass-by-value
In this pass-by-value, a copy of the object is passed to the function. Any changes made inside the function do not affect the original object.
Example:
#include <iostream>
using namespace std;
class Calculator {
public:
int a, b;
Calculator(int a, int b) : a(a), b(b) {}
// Function to calculate the sum of a and b
int sum() {
return a + b;
}
};
// Function that takes a Calculator object by value
void displaySum(Calculator c) {
cout << "The sum is: " << c.sum() << endl;
}
int main() {
Calculator c(500, 100); // Creating an object of Calculator
displaySum(c); // Passing the object by value
return 0;
}
Output:
The sum is: 600
Explanation:
In this example, the displaySum() function takes a Calculator object by value. A copy of the object `c` is passed to the function, so any modifications to `c` inside displaySum() will not affect the original object `c`.
Pass-by-reference
In this pass-by-reference, the original object itself is passed to the function, meaning any changes made inside the function will reflect on the original object.
Example:
#include <iostream>
using namespace std;
class Calculator {
public:
int a, b;
Calculator(int a, int b) : a(a), b(b) {}
// Function to calculate the sum of a and b
int sum() {
return a + b;
}
// Function to change the values
void changeValues(int n1, int n2) {
a = n1;
b = n2;
}
};
// Function that takes a Calculator object by reference
void modifyValues(Calculator &c) {
c.changeValues(20, 10); // Modifying the original object
}
int main() {
Calculator c(10, 5); // Creating an object of Calculator
cout << "Original sum: " << c.sum() << endl;
modifyValues(c); // Passing the object by reference
cout << "Modified sum: " << c.sum() << endl;
return 0;
}
Output:
Original sum: 15
Modified sum: 30
Explanation:
In this example, the modifyValues() function takes the Calculator object `c`. Since it’s passed by reference, any changes made to `c` inside modifyValues() will modify the original object `c`.
Pass-by-pointer
In this pass-by-pointer, the address (pointer) of the object is passed to the function. Similar to pass-by-reference, any changes made inside the function affect the original object.
Example:
#include <iostream>
using namespace std;
class Calculator {
public:
int a, b;
Calculator(int a, int b) : a(a), b(b) {}
// Function to calculate the sum of a and b
int sum() {
return a + b;
}
// Function to change the values
void changeValues(int n1, int n2) {
a = n1;
b = n2;
}
};
// Function that takes a pointer Calculator object
void modifyValues(Calculator *c) {
c->changeValues(20, 10); // Modifying the original object
}
int main() {
Calculator c(10, 5); // Creating an object of Calculator
cout << "Original sum: " << c.sum() << endl;
modifyValues(&c); // Passing the object by reference
cout << "Modified sum: " << c.sum() << endl;
return 0;
}
Output:
Original sum: 15
Modified sum: 30
Explanation:
In this example, the modifyValues() function takes a pointer to the Calculator object `c`. Inside the function, the arrow operator (->) is used to access the members of the object via the pointer. Modifications to the `c` object affect the original object `c`.
Conclusion
C++ programming language is rich in features supporting procedural programming, object-oriented programming, and generic programming. With the understanding of class and object, constructor the destructor, accessing the data members and functions, etc., there is the ability to develop effective and manageable applications. These topics form the core subjects in C++ programming for both beginners and advanced learners and provide room and control in the development of software.
FAQs
What is the difference between a class and an object in C++?
A class is a blueprint or template that defines the structure and behaviour (methods) of objects. An object is an instance of a class, representing a specific entity that holds the values of the class attributes.
What are constructors in C++ and how do they work?
Constructors are a type of member function that is invoked automatically when an object of the class is constructed. They perform the initialisation of the objects and are overemphasised and one can do so for various forms of such initialisations.
What is the function of a destructor in C++?
Destructors are special member functions in an object’s memory that would enable one to destroy the object. They aim to release any resources like memory or file handles that were acquired during the lifetime of the object.
What does inheritance mean in C++, and why is it important?
A class (derived class) can inherit methods and properties from another class (base class) through inheritance. This helps build class structures that have hierarchy levels and minimises cases of rewriting similar code.
What is the difference between a runtime polymorphism and a compile-time polymorphism?
More dynamic and adaptable behaviour in code is made possible by runtime polymorphism, which is accomplished via virtual functions. Compile-time polymorphism, on the other hand, is a polymorphism that occurs at the stage of compiling the code and is made up of the operator and function overloading.
Hero Vired is a leading LearnTech company dedicated to offering cutting-edge programs in collaboration with top-tier global institutions. As part of the esteemed Hero Group, we are committed to revolutionizing the skill development landscape in India. Our programs, delivered by industry experts, are designed to empower professionals and students with the skills they need to thrive in today’s competitive job market.