I'm writing a piece of code in which I'd like to use a different constructor of a class depending on a condition. So far I've used if
and else
statements to construct the object, but the instance is then 'trapped' in the brackets and can't be used further in the code.
Here is what it looks like in code:
if (my_boolean){
MyClass my_object(arg1); //calling a first constructor
}
else {
MyClass my_object(arg1,arg2); //calling another constructor
}
//more code using my_object
I tried using the static
keyword without success so far. Is there a common way of conditionally using different constructors without having to redefine the constructors?
try the following :)
MyClass my_object = my_boolean ? MyClass(arg1) : MyClass(arg1,arg2);
Take into account that this code will work even if the class has no default constructor.
Here is a demonstrative example
#include <iostream>
#include <cstdlib>
#include <ctime>
int main ()
{
struct Point
{
Point( int x ) : x( x ) {}
Point( int x, int y ) : x( x ), y( y ) {}
int x = 0;
int y = 0;
};
std::srand( ( unsigned )std::time( 0 ) );
Point p = std::rand() % 2 ? Point( 1 ) : Point( 1, 2 );
std::cout << "p.x = " << p.x << ", p.y = " << p.y << std::endl;
return 0;
}
I have gotten the following output
p.x = 1, p.y = 2
What output have you gotten? :)
If you want to use a variable outside of a given scope, it must be declared outside that scope.
void foo()
{
MyClass my_object;
if (my_boolean){
my_object = MyClass(arg1); //calling a first constructor,
//then copy or move assignment
}
else {
my_object = MyClass(arg1,arg2); //calling another constructor,
//then copy or move assignment
}
//more code using my_object
}
//Can no longer access my_object
If you want to do it this way, I suggest defining a move assignment operator if the default will not work for your purposes (or there isn't a default move assignment operator).
Also, the code where you are using my_object
may be cleaner if you move the if
/else
blocks and object construction to a separate function, then do something like:
MyClass my_object = make_object(my_boolean);
Or, if arg1
and arg2
aren't global,
MyClass my_object = make_object(my_boolean, arg1, arg2);
If creating an object gets more complicated than what you've asked about here, you may wish to look into the factory pattern.
You can use a smart pointer instead of a direct instance:
std::unique_ptr<MyClass> my_object;
if (my_boolean) {
//calling a first constructor
my_object.reset(new MyClass(arg1));
}
else {
//calling another constructor
my_object.reset(new MyClass(arg1,arg2));
}
//more code using my_object
In contrast to some other solutions proposed here, this will also work for bigger if() {} else if() {}
sequences, or switch
blocks.
In case you can't use a compiler capable of the latest standard, you can use the good old std::auto_ptr
in the exactly same manner.
"I tried using the static
keyword without success so far."
Good so! A static
variable is certainly not what you want here.