1. Home
C++ Tutorial

Explore C++ Tutorials: Exploring the World of C++ Programming

Discover comprehensive C++ tutorials designed for beginners and advanced programmers alike. Enhance your coding skills with step-by-step guides and practical examples.

  • 77 Lessons
  • 15 Hours
right-top-arrow
18

Constructor in C++: A Comprehensive Guide with Examples

Updated on 24/09/2024425 Views

Constructors are an important component of object-oriented programming in C++. They are special member functions within a class playing a crucial role in the creation and initialization of objects. They are blueprints for how an object should be constructed, ensuring that it starts its life in a valid and usable state.

I will teach you how to use a constructor in C++ in this tutorial and we will explore the different types of constructors we have available to us. Let us dive in and learn everything you need to know about constructors.

What is a Constructor in C++?

In the world of C++, a constructor is a special kind of member function that shares the same name as its class. It is automatically called whenever a new object of that class is created. The primary responsibility of a constructor in C++ is to initialize the object's data members, i.e., the variables that define the object's attributes and state.

Why Use Constructors?

Constructors are indispensable for several reasons:

  • Guaranteed Initialization: By using constructors, we ensure that all objects of our class are properly initialized with valid data. This prevents objects from starting with random or undefined values, which can lead to unexpected behavior and errors.
  • Usable State: Constructors set up the object in a way that makes it immediately usable. For example, a BankAccount object might be initialized with a starting balance, an Employee object with a name and ID, or a Game object with the initial game state.
  • Encapsulation: Constructors encapsulate the initialization logic within the class itself. This makes our code more organized, easier to understand, and less prone to errors. It also hides the internal details of object creation from the rest of our code.
  • Readability and Maintainability: Constructors make our code more readable by explicitly defining how an object is created. This is especially helpful when we have complex objects with multiple attributes.

Basic Constructor Syntax

This is the C++ constructor syntax:

class ClassName {

public:

// Constructor declaration (name same as constructor)

ClassName(parameter1, parameter2, ...); // Parameterized constructor (optional)

// ... other members (data and functions) ...

};

In the above C++ constructor syntax:

  • Class Name: The constructor's name must be identical to the class name.
  • No Return Type: Constructors do not have a return type, not even void.
  • Parameters (Optional): We can optionally define parameters to pass values for initializing data members.

Constructor Implementation (Outside Class Definition)

Here is the implementation of a constructor in C++:

// Constructor definition

ClassName::ClassName(parameter1, parameter2, ...)

: memberInitializerList (optional)

{

// Constructor body (for additional initialization)

}

In the above snippet:

  • :: (Scope Resolution Operator): Indicates that the function belongs to the specified class.
  • Member Initializer List (Optional): A more efficient way to initialize data members directly.
  • Constructor Body: Contains code to perform any other necessary initialization tasks.

Real-world example:

class Person {

public:

Person(std::string n, int a) : name(n), age(a) {} // Constructor

private:

std::string name;

int age;

};

int main() {

Person alice("Alice", 30); // Constructor called automatically

// ...

}

In this constructor in C++ example, the Person constructor initializes the name and age members when a Person object is created.

Constructor Types in C++

C++ offers various types of constructors, each serving a specific purpose in object creation and initialization.

Default Constructor in C++

A C++ default constructor is a constructor that takes no arguments. Its main purpose is to provide a basic way to create objects without explicitly setting initial values. If we do not define any constructor in a class, the compiler automatically generates a default constructor for you.

Example:

class Point {

public:

Point() : x(0), y(0) {} // Default constructor

private:

int x;

int y;

};

In the above example, the default constructor Point() initializes the x and y coordinates to zero.

Parameterized Constructor in C++

A parameterized constructor in C++ accepts one or more arguments, allowing us to customize how an object is initialized when created. The arguments passed to the cpp constructor are used to set the initial values of the object's data members.

Example:

class Rectangle {

public:

Rectangle(double w, double h) : width(w), height(h) {} // Parameterized constructor

private:

double width;

double height;

};

Here, the Rectangle constructor takes two arguments (w and h) to set the width and height of the rectangle object.

Copy Constructor in C++

A copy constructor is a special constructor used to create a new object as an exact copy of an existing object of the same class. It is essential for situations where we need to duplicate an object, such as when passing objects by value to functions or returning objects from functions.

Example:

class Person {

public:

Person(const Person& other) : name(other.name), age(other.age) {} // Copy constructor

// ...

};

In this example, the copy constructor of Person takes a reference to another Person object (other) and copies its name and age.

Move Constructor in C++

Introduced in C++11, move constructors are designed to efficiently transfer ownership of resources (like dynamically allocated memory) from one object to another. This is done without creating a full copy, making it much faster in scenarios where copying would be expensive.

Example:

class MyString {

public:

MyString(MyString&& other) noexcept

: data(std::move(other.data)), size(other.size)

{

other.data = nullptr;

other.size = 0;

}

// ...

};

In the MyString move constructor, the data pointer and size from other are transferred, and then other's data is set to nullptr to avoid potential double-free errors.

If you wish to learn how to code in C++, you can check out upGrad’s software engineering courses.

Constructor Program in C++

Here is a cpp constructor program that you can run and try out yourself:

Code:

#include <iostream>

#include <string>

class Car {

private:

std::string brand;

std::string model;

int year;

double price;

public:

// Default constructor

Car() {

brand = "Unknown";

model = "Unknown";

year = 0;

price = 0.0;

std::cout << "Default constructor called.\n";

}

// Parameterized constructor

Car(std::string b, std::string m, int y, double p) : brand(b), model(m), year(y), price(p) {

std::cout << "Parameterized constructor called.\n";

}

// Copy constructor

Car(const Car& other) {

brand = other.brand;

model = other.model;

year = other.year;

price = other.price;

std::cout << "Copy constructor called.\n";

}

// Display car information

void displayInfo() {

std::cout << "Brand: " << brand << "\nModel: " << model

<< "\nYear: " << year << "\nPrice: $" << price << std::endl;

}

};

int main() {

// Using the default constructor

Car car1;

car1.displayInfo();

// Using the parameterized constructor

Car car2("Toyota", "Camry", 2023, 25000.0);

car2.displayInfo();

// Using the copy constructor

Car car3(car2);

car3.displayInfo();

return 0;

}

In the above constructor in C++ example, we define a Car class to represent cars. The class includes four private data members: brand, model, year, and price.

We have implemented these constructors in the program:

  1. Default Constructor (Car()): This constructor initializes a car object with default values ("Unknown" for brand and model, 0 for year, and 0.0 for price). It is called automatically when we create a Car object without providing arguments, as seen with car1.
  1. Parameterized Constructor (Car(std::string, std::string, int, double)): This constructor takes arguments to initialize the Car object with specific values. We use it to create car2 with details like brand, model, year, and price.
  1. Copy Constructor (Car(const Car&)): This constructor is used to create a new Car object (car3) as an exact copy of an existing Car object (car2).

In the main function, we create three Car objects: one using the default constructor, one using the parameterized constructor, and one using the copy constructor. We then call the displayInfo member function for each car to print its details to the console. The output will demonstrate how each constructor initializes the objects differently, showcasing the flexibility and utility of constructors in object creation and initialization.

C++ Constructor Overloading

In C++, just like we can overload functions (have multiple functions with the same name but different parameters), we can also overload constructors. This means that we can have multiple constructors within the same class, each with a distinct parameter list. The compiler intelligently selects the appropriate constructor to call based on the arguments you provide when creating an object.

Why Overload Constructors?

Constructor in C++ overloading offers flexibility and convenience. It allows us to create objects in different ways, tailored to the specific needs of your program. Here are a few reasons why you might want to overload constructors:

  • Different Initialization Scenarios: We might want to create objects with default values, with specific values provided as arguments, or by copying an existing object.
  • Convenience: Overloading provides multiple ways to construct objects, making our code easier to use in different contexts.
  • Reduced Code Duplication: We can avoid redundant code by delegating common initialization tasks to a base constructor and using specialized constructors for variations.

When we create an object, the C++ compiler analyzes the arguments we pass and selects the most suitable constructor based on:

  • Number of Arguments: The compiler first looks for a constructor in C++ that matches the number of arguments you provided.
  • Argument Types: If multiple constructors have the same number of arguments, the compiler then checks the types of the arguments to find the best match.
  • Implicit Conversions: If no exact match is found, the compiler might try to implicitly convert your arguments to types that fit a constructor's parameters. However, this is generally discouraged, as it can lead to unintended behavior.

Example:

class Box {

public:

Box() {

length = 1.0;

width = 1.0;

height = 1.0;

}

Box(double side) : length(side), width(side), height(side) {}

Box(double l, double w, double h) : length(l), width(w), height(h) {}

private:

double length;

double width;

double height;

};

int main() {

Box box1; // Calls the default constructor (all sides = 1.0)

Box box2(5.0); // Calls the constructor with one argument (cube)

Box box3(2.0, 3.0, 4.0); // Calls the constructor with three arguments

}

In this constructor in C++ example, the Box class has three overloaded constructors:

  • Box(): The default constructor creates a cube with all sides set to 1.0.
  • Box(double side): This constructor creates a cube with the specified side length.
  • Box(double l, double w, double h): This constructor creates a box with the given length, width, and height.

Special Considerations for Constructor in C++

Let us now look at some special considerations that will help you write more robust and efficient code when designing classes and using constructors.

Implicit vs. Explicit Constructors

In C++, a single-argument constructor can sometimes lead to implicit conversions, which might not always be desirable.

Example:

class MyString {

public:

MyString(int size) { /* ... */ } // Single-argument constructor

// ...

};

MyString str = 10; // Implicit conversion: int 10 is used to create a MyString object

In this code, the single-argument constructor MyString(int size) can be called implicitly when we assign an integer value (10) to a MyString object. This might not be what we intended, as it can lead to unexpected behavior.

To prevent such implicit conversions, we can declare a single-argument constructor as explicit.

Example:

class MyString {

public:

explicit MyString(int size) { /* ... */ } // Explicit constructor

// ...

};

MyString str = 10; // Error! Explicit constructor cannot be called implicitly

MyString str2(10); // Correct way to call the explicit constructor

The explicit keyword forces us to explicitly call the constructor with the correct type, preventing unintended conversions.

Constructor Delegation

When we have multiple constructors, we might find that they share some common initialization logic. To avoid code duplication, C++11 introduced constructor delegation, which allows one constructor to call another constructor within the same class.

Example:

class Person {

public:

Person() : Person("", 0) {} // Delegates to the parameterized constructor

Person(std::string n, int a) : name(n), age(a) {}

private:

std::string name;

int age;

};

In this case, the default constructor in C++ delegates to the parameterized constructor, effectively reusing the initialization code.

Default Member Initialization

C++ allows us to provide default values for your class's member variables directly in the class definition. This is useful when we want members to have certain initial values even if a constructor does not explicitly set them.

Example:

class Product {

public:

Product() {} // No initialization in the constructor

private:

std::string name = "Unnamed";

double price = 0.0;

};

In this example, even though the constructor is empty, the name and price members will have default values when a Product object is created.

Derived Class Constructor C++

In C++, when we create a derived class (a class that inherits from a base class), constructor interactions play a crucial role in properly initializing both base and derived class members.

Here is how it works:

  • Base Class Constructor Call: Before the derived C++ constructor class body is executed, the constructor of its base class is automatically called. This ensures that the base class members are initialized first.
  • Order of Construction: The order of constructor calls follows the inheritance hierarchy. If the base class itself is derived from another class, that grandparent class's constructor is called first, and so on, up the inheritance chain.

Here is the constructor in C++ delegation in derived classes:

  • Implicit Delegation: By default, the derived class constructor implicitly calls the base class's default constructor (the constructor with no arguments).
  • Explicit Delegation: You can explicitly call a specific base class constructor using the member initializer list. This is necessary if the base class doesn't have a default constructor or if you want to use a different base class constructor.

Final Tips

The use of constructors streamlines object creation, ensures proper initialization, and makes the code more organized and maintainable. Finally, I would also like to mention that constructors can be much more elaborate, handling complex initialization logic and resource management. To gain a solid foundation in C++ programming, I would definitely recommend you practice using constructors in your programs.

If you wish to learn programming languages such as C++, you can check out upGrad’s computer science programs such as the Master’s in Computer Science Program.

Frequently Asked Questions

  1. What is a constructor in C++?

A constructor in C++ is a special member function of a class that shares its name with the class and is automatically called when an object of that class is created.

  1. What is the purpose of a constructor?

The primary purpose of a constructor in C++ is to initialize the object's data members and put the object in a valid state before it's used.

  1. How is a constructor different from a regular member function?

Unlike regular member functions, constructors have no return type (not even void) and are invoked automatically during object creation.

  1. Can a class have multiple constructors?

Yes, a class can have multiple constructors with different parameter lists, a concept known as constructor overloading.

  1. What is a default constructor?

A default constructor in C++ is a constructor that takes no arguments or has default values for all its parameters.

  1. Can constructors be overloaded like other functions?

Yes, constructors can be overloaded just like regular member functions, allowing us to create objects in different ways.

  1. What is the role of a copy constructor?

A copy constructor in C++ creates a new object as an exact copy of an existing object of the same class.

  1. Can constructors be virtual?

No, constructors cannot be virtual in C++.

Kechit Goyal

Kechit Goyal

Team Player and a Leader with a demonstrated history of working in startups. Strong engineering professional with a Bachelor of Technology (BTech…Read More

Need Guidance? We're Here to Help!
form image
+91
*
By clicking, I accept theT&Cand
Privacy Policy
image
Join 10M+ Learners & Transform Your Career
Learn on a personalised AI-powered platform that offers best-in-class content, live sessions & mentorship from leading industry experts.
right-top-arrowleft-top-arrow

upGrad Learner Support

Talk to our experts. We’re available 24/7.

text

Indian Nationals

1800 210 2020

text

Foreign Nationals

+918045604032

Disclaimer

upGrad does not grant credit; credits are granted, accepted or transferred at the sole discretion of the relevant educational institution offering the diploma or degree. We advise you to enquire further regarding the suitability of this program for your academic, professional requirements and job prospects before enr...