Post

How to Avoid "The Default Constructor Cannot Be Referenced -- It Is a Deleted Function" Error in C++

Introduction

In C++, the error message The Default Constructor Cannot Be Referenced -- It Is a Deleted Function can occur when working with derived classes and base classes. This technical document provides insights into this scenario and offers strategies to avoid the issue in C++ programming.

Table of Contents

Understanding the “Default Constructor Cannot Be Referenced” Error

The error message The Default Constructor Cannot Be Referenced -- It Is a Deleted Function indicates that the default constructor of a class has been explicitly deleted, making it inaccessible for creating objects. It can occur when working with derived classes and base classes in C++. In which scenario it indicates that the default constructor of the base class is not accessible or deleted, preventing the derived class from using it.

Handling Derived Classes and Base Classes

In C++, when a derived class is created, it implicitly calls the default constructor of its base class. If the default constructor of the base class is not available or explicitly deleted, attempting to create objects of the derived class will result in the Default Constructor Cannot Be Referenced error.

Avoiding the Issue

To avoid the “Default Constructor Cannot Be Referenced” error in scenarios involving derived classes and base classes, consider the following strategies:

Define a Default Constructor

If your class lacks a default constructor, define one explicitly. A default constructor has no parameters or has all parameters with default values. By providing a default constructor, you allow the creation of objects without arguments, preventing the error. Here’s an example:

1
2
3
4
5
6
   class MyClass {
   public:
       MyClass() {
           // Default constructor implementation
       }
   };

Avoid Deleting the Default Constructor

If you have explicitly deleted the default constructor in your class declaration, remove the deleted function declaration. When a constructor is deleted using the = delete syntax, it prevents the compiler from generating a default constructor. By removing this deletion, the default constructor will be available again.

Provide Non-Default Constructors

If your class has constructors with parameters only, ensure that you always provide the necessary arguments when creating objects. This approach avoids relying on the default constructor and eliminates the error. Example:

1
2
3
4
5
6
7
8
9
10
11
12
   class MyClass {
   public:
       MyClass(int value) {
           // Constructor implementation
       }
   };
   
   int main() {
       MyClass obj(42); // Creating an object using the non-default constructor
       // Rest of the code
       return 0;
   }

Use Initialization Lists

In C++, references must be initialized upon declaration and cannot be left uninitialized.

If you have a non-default constructor that initializes member variables, ensure that you use initialization lists to assign values to these variables. Initialization lists provide a way to initialize member variables before the body of the constructor is executed. By using initialization lists, you can avoid relying on the default constructor. Example:

1
2
3
4
5
6
7
8
9
   class MyClass {
   private:
       int value;
   
   public:
       MyClass(int newValue) : value(newValue) {
           // Constructor implementation
       }
   };

Inheriting Constructors

In C++11 and later versions, you can use the “inheriting constructors” feature to automatically inherit constructors from the base class. By adding using BaseClass::BaseClass; in the derived class, the constructors of the base class become accessible. This allows the derived class to utilize the constructors of the base class. For example:

1
2
3
4
5
6
7
8
9
10
11
class BaseClass {
public:
    BaseClass(int value) {
        // Constructor implementation
    }
};

class DerivedClass : public BaseClass {
public:
    using BaseClass::BaseClass; // Inherit constructors from BaseClass
};

This way, the derived class can use the constructors of the base class, including the default constructor if available.

Explicitly Defining Constructors

Alternatively, you can explicitly define constructors in both the derived class and the base class. This allows you to control the initialization of the derived class while ensuring that the base class is properly constructed. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
class BaseClass {
public:
    BaseClass(int value) {
        // Constructor implementation
    }
};

class DerivedClass : public BaseClass {
public:
    DerivedClass(int value) : BaseClass(value) {
        // Derived class constructor implementation
    }
};

By explicitly defining the constructors, you can ensure that the base class is properly initialized while providing additional functionality specific to the derived class.

Conclusion

By understanding the scenarios involving derived classes and base classes, and applying the appropriate strategies, you can avoid the The Default Constructor Cannot Be Referenced -- It Is a Deleted Function issue in C++.

Inheriting constructors or explicitly defining constructors in both the derived class and the base class enable proper initialization and ensure the constructors are accessible for object creation. Following these simple practices enhances the reliability and flexibility of your C++ programs.

This post is licensed under CC BY 4.0 by the author.