Reputation: 63
Can I have a constructor work in different ways if the argument is of different type? i.e. int or float.
Let's say that if I do, new Object(3) the constructor fills an array with 3 at every index
Let's say that if I do, new Object(3.5) the constructor fills an array with index+3.5 for every index
Let's say that if I do, new Object() the constructor fills an array with 0.0 at every index
Is there a way to achieve this with just one constructor? Or do I need three different constructors?
Thanks.
Upvotes: 1
Views: 3681
Reputation: 10254
As long as the parameter passed is always of the same type you can get away with using one constructor, otherwise you need several.
It seems as though the most obvious solution to this would be to insert a switch statement inside your object constructor.
Example:
public Object(int num)
{
switch (num)
{
case 1: array[i] = num;
break
case 2: array[i] = num * 2;
}
}
Upvotes: 1
Reputation: 25581
It sounds like you're up for a maintenance nightmare. I suggest yo use the named constructor idiom instead:
class Object
{
public:
// Sets all elements to 0.
Object();
// Sets all elements to value.
static Object Fill(double value);
// Sets all elements to the previous + delta, beginning at start.
static Object Accumulate(double start, double delta);
};
Upvotes: 2
Reputation: 792089
It is usually a bad idea to have such different behaviour for a constructor purely based on the type of the parameter, especially for built-in types that are easily implicitly convertible between each other.
Having said that, purely as a programming exercise, it is possible to do this using one constructor, but you would have to use a proxy class with implicit conversion from the types to be distinguished between to achieve what you want. As a pre-canned solution, boost::variant would fit the requirement. You may not consider this to meet the requirements of a single constructor, as it relies on multiple constructors (or a constructor template) of a second class.
class Object
{
public:
Object( const boost::variant< int, double >& val = 0 )
{
switch( val.which() )
{
case 0:
// TODO: Fill array with val
break;
case 1:
// TODO: fill array with val + index
break;
}
}
// TODO: Add array member
};
Upvotes: 1
Reputation: 73443
Use 3 different constructors as the logic is different depending upon the type of the parameter. Also, be aware of the type promotions done by the compiler..otherwise you might end up with surprises when the code is executed.
Upvotes: 0
Reputation: 95
You can factor the behavior Object()
and Object(3)
because they do the same thing. Just write your constructor like this:
class Object {
// fills an array with n at every index
Object(int n = 0) { ... }
};
The problem is that the constructor with a float (3.5 in the example) has to be separated, like this:
class Object {
// fills an array with n at every index
Object(int n = 0) { ... } // handles Object() AND Object(3)
// fills an array with index + n at every index
Object(float n) { ... } // handles Object(3.5)
};
Upvotes: 0
Reputation: 76001
No only you need three different constructors, you want three different constructors. It'll keep the code cleaner and easier to understand, maintain and unit test.
Upvotes: 0
Reputation: 69505
Of course you can have many constructors! Overloading for constructors work the same as for any function/member.
Just remember that sometimes compiler can implicitly call a constructor that you wouldn't like to have been called - by automatic conversion of arguments.
You can add keyword explicit to the constructor declaration to forbid any automatic conversion.
Upvotes: 7
Reputation: 1168
You can do it with one constructor, but it will be ugly as hell. A 3 constructors approach is proffered because it separates the usage and simplify the code.
Upvotes: 3
Reputation: 1099
If you only care about built in types you can take advantage of type promotions and default values:
struct Object
{
Object(double value = 0.0)
{
// do that thing you do
}
};
Upvotes: 1
Reputation: 17627
You will either need three different constructors (overloading them) or one with some attributes with default values.
This can be achieved, however I would suggest using 3 different constructors for code clarity, etc.
Upvotes: 0
Reputation: 24936
Multiple constructors would be required, one for each different argument type.
Upvotes: 0