Problem with Single Argument Constructor in C++ and How to solve it
Last Updated :
25 Feb, 2022
In C++, if a class has a constructor which can be called with a single argument, then this constructor becomes a conversion constructor because such a constructor allows automatic conversion to the class being constructed.
Problem:
Whenever there is a constructor with a single argument and there is a function that takes an argument of the same class type but when this function is called using an argument type same as that of the constructor, in that case, the function gets called successfully. This is because the argument is implicitly converted to the class type by the constructor. The argument gets passed to the constructor and then the function gets executed. This is something we would not expect.
Below is the C++ program that demonstrates the above problem:
C++
#include <iostream>
using namespace std;
class GfG {
int data;
public :
GfG( int a)
: data(a)
{
}
GfG() {}
void display()
{
cout << "Value of data is: " << data;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
int var = 10;
func(var);
}
|
Output
Value of data is: 10
Explanation:
In the above code, there is a user-defined constructor that takes an argument of type GFG (class type) and there is a function that also takes an argument of class type. When there is an attempt to invoke the function by passing int type parameter, in this case, the function is called successfully. This happens because of the user-defined constructor. The int value passed to the function is implicitly converted to class type and the data member gets initialized with the value of the passed parameter (var).
Solution:
In order to avoid this problem of implicit conversion is to make the constructor explicit. Below is the C++ program to demonstrate the solution to the implicit conversion problem-
C++
#include <iostream>
using namespace std;
class GfG {
int data;
public :
explicit GfG( int a)
: data(a)
{
}
GfG() {}
void display()
{
cout << "Value of data is: " << data;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
int var = 10;
func(var);
}
|
Output:

Drawback:
This approach, however, has some drawbacks. What if in the same program the user really wants to convert int data type to class data type and assign an int value to an object of the class. The following assignment will result in an error-
int var = 10;
GfG obj = var; // This will result in error
To solve this problem you can explicitly convert var to GfG and then assign it to obj.
GfG obj = (GfG) var; // This works fine
Below is the C++ program to implement the above approach-
C++
#include <iostream>
using namespace std;
class GfG {
int data;
public :
explicit GfG( int a)
: data(a)
{
}
GfG() {}
void display()
{
cout << "Value of data is: " << data;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
int var = 10;
GfG obj = (GfG)var;
func(obj);
}
|
Output
Value of data is: 10
Let’s consider one more example and discuss what happens when explicit will also not work.
C++
#include <iostream>
using namespace std;
class GfG {
private :
string str;
public :
GfG( int a)
{
str.resize(a);
}
GfG( const char * string)
{
str = string;
}
void display()
{
cout << "String is: " << str << "\n" ;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
GfG obj = 'x' ;
func(obj);
return 0;
}
|
Output
String is:
Explanation:
In the above example, the user is trying to initialize a string with a char value but char is a part of the integer family, so the compile will use the constructor GfG(int) to implicitly convert char to GfG. This will produce unexpected results.
As discussed above one of the solutions to this problem is to use the keyword explicit.
C++
#include <iostream>
using namespace std;
class GfG {
private :
string str;
public :
explicit GfG( int a)
{
str.resize(a);
}
GfG( const char * string)
{
str = string;
}
void display()
{
cout << "String is: " << str << "\n" ;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
GfG obj = 'x' ;
func(obj);
return 0;
}
|
Output:

Explanation:
The above program will not compile, since GfG(int) was made explicit, and an appropriate converting constructor could not be found to implicitly convert ‘x’ to GfG. Please note that explicit keywords can only disallow implicit conversions, typecasting cannot be avoided using the explicit keyword as discussed above.
The delete keyword
One partial solution to the above problem is to create a private constructor GfG(char). Below is the C++ program to implement this concept:
C++
#include <iostream>
using namespace std;
class GfG {
private :
string str;
GfG( char )
{
}
public :
explicit GfG( int a)
{
str.resize(a);
}
GfG( const char * string)
{
str = string;
}
void display()
{
cout << "String is: " << str << "\n" ;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
GfG obj = 'x' ;
func(obj);
return 0;
}
|
Output:

Explanation:
In the above code, GfG(char) constructor is made private. This has prevented access to the constructor from outside the class but it can still be used inside the class. The solution to this problem is to use the delete keyword.
Delete Keyword:
Below is the C++ program to implement the concept of delete keyword:
C++
#include <iostream>
using namespace std;
class GfG {
private :
string str;
GfG( char ) = delete ;
public :
explicit GfG( int a)
{
str.resize(a);
}
GfG( const char * string)
{
str = string;
}
void display()
{
cout << "String is: " << str << "\n" ;
}
};
void func(GfG o)
{
o.display();
}
int main()
{
GfG obj = 'x' ;
func(obj);
return 0;
}
|
Output:

Explanation:
When a function is deleted, any use of that function is a compile-time error.
Similar Reads
How to Retrieve Command-Line Arguments in C++?
Command-line arguments are the values or parameters that are passed after the name of the program through the command line or terminal when the program is executed. In this article, we will learn how to retrieve command-line arguments in C++. Retrieving Command Line Arguments in C++To access all the
2 min read
How to Parse Command Line Arguments in C++?
In C++, command line arguments are parameters that are passed to a program when it is invoked via command line or terminal. In this article, we will learn how to parse command line arguments in C++. Parse Command Line Arguments in C++In C++, we can parse the command-line arguments using the argc and
2 min read
How to Define a Move Constructor in C++?
In C++, we have a move constructor which is a part of C++11 move semantics and is used to handle resources for temporary and rvalue objects. In this article, we will learn how to write a move constructor in C++. How to Write Move Constructor in C++?The move constructor is defined similarly to a copy
2 min read
How to Use Initializer Lists in Constructors in C++?
In C++, the initializer list in constructors can be used to initialize member variables with a list of values. In this article, we will learn how to use initializer lists in the constructor in C++. Initializer List in Constructor in C++We can use initializer_lists in constructors for initializing th
2 min read
How to Use Default Arguments in Function Overloading in C++?
In C++, we can provide the default values for the input arguments into the functions and it is also supported in function overloading. In this article, we will learn how to use default arguments in function overloading in C++. Default Arguments in Function Overloading in C++We can define the default
2 min read
NULL undeclared error in C/C++ and how to resolve it
What is undeclared Error: When we use some constant in our program maybe they are built-in constant and may be created by a user according to the requirement. But when we use some constant, and they are not built-in and also not defined by a user in that condition, we get an undeclared error. Below
3 min read
How to Create a Pointer to a Function in C++?
In C++, a function pointer is a variable that stores the address of a function that can later be called through that function pointer. It is useful for passing functions as parameters to other functions(callback functions) or storing them in data structures. In this article, we will learn how to use
2 min read
How to Resolve a Name Conflict in C++?
In C++, naming conflict occurs when two identifiers in the same scope have the same name and the compiler cannot infer which identifier to refer to when it is mentioned in the program. In this article, we will discuss what are name conflicts, what are its causes, and how to resolve the name conflict
4 min read
How to Write Getter and Setter Methods in C++?
In C++, classes provide a way to define custom data types that can encapsulate data and methods related to that data. Getter and setter methods are commonly used to access and modify private member variables of the class allowing for the controlled access and modification of data. In this article, w
2 min read
How to Implement a Copy Constructor in a Derived Class in C++
In object-oriented programming, a copy constructor is a special member function that initializes a new object as a copy of an existing object. In this article, we will learn how to implement a copy constructor in a derived class. Implementing Copy Constructor in a Derived Class in C++ In C++, when w
3 min read