I am making a class in C++ and I need two default constructors with the same arguments. The only argument they need to take is a vector. Depending on the data that is given in the vector I need to do something different and the way the data is given it is impossible to tell which constructor the user wants.
Should I create two default constructors, the first one takes a vector and int as arguments, the second takes a vector and char as argument. Then in the documentation explain which constructor you are using when you give me either an int or char.
Or should I use one default constructor that takes a vector and int, then in the documentation state that when creating your object, 0 for the int argument will give you one constructor and 1 for the int argument will use the other constructor.
Or is there a better way that I don't know about like using keywords or something with templates like this:
What is the standard convention when creating multiple default constructors with the same arguments?
There is no convention, since it's illegal.
Note: a default constructor is any constructor which can be called with zero arguments (with or without default arguments.)
Second, this looks like an XY problem ( http://xyproblem.info/ ): what problem are you trying to solve?
In other words, what is your use case: why do you want this?
Depending on the data that is given in the vector I need to do something different and the way the data is given it is impossible to tell which constructor the user wants.
If it's impossible to tell what the user wants, how do you write the program to call the right constructor?
MyClass(bool firstWay, const vector<double> & sample)
{
if (firstWay)
{
// construct the first way
}
else
{
// construct the second way
}
}
The disadvantage with this approach is that you need to write both implementations in the same constructor and you get an additional branch. It's also not very clear what true or false means when constructing the objects.
enumclass ConstructionMethod
{
first, second
};
MyClass(ConstructionMethod constructionMethod, const vector<double> & sample)
{
switch (constructMethod)
{
case MyClassConstructionMethod::first:
// construct the first way
break;
case MyClassConstructionMethod::second:
// construct the second way
break;
}
}
This is almost the same as passing a bool but you can use more descriptive names than true and false which makes the code more readable when constructing the objects.
It also gets easier if you later want to add additional construction methods without breaking existing code.
Solution #3 - Pass empty class objects
1 2 3 4 5 6 7 8 9 10 11 12
class FirstConstructionMethod {};
class SecondConstructionMethod {};
MyClass(FirstConstructionMethod, const vector<double> & sample)
{
// construct the first way
}
MyClass(SecondConstructionMethod, const vector<double> & sample)
{
// construct the second way
}
This allows you to use two separate constructors, which is great. Construction of the objects should have the same level of readability as enums.
One small disadvantage with this approach is that it takes a little more work if you want to decide between the different construction methods at runtime.
static MyClass createFirst(const vector<double> & sample)
{
MyClass obj;
// construct obj the first way
return obj;
}
static MyClass createSecond(const vector<double> & sample)
{
MyClass obj;
// construct obj the second way
return obj;
}
This is quite nice actually. It's like having named constructors. Since the functions are members of the class you have full access to all the private members of the class. If you for example don't want the user to be able to use the default constructor (the one that takes no arguments) you can simply make it private and still use it from inside these function.
thanks everyone for your answers, I guess I didn't type what I meant correctly. I have a default constructor, but what i meant to say is I need two more constructors and both of these constructors take in the same argument. I will try Peter87's solutions out.
Or you could be, y'know, really radical, and answer the question mbozzi asked you. If we knew what it is you're actually trying to achieve, we could actually help you find the right solution.
@MikeyBoy, I appreciate the help but all I needed was to know if it was possible and what the idea is, I can figure it out from here, also I don't want anyone to do my work for me. I also wasn't specific so that if someone that is learning c++ needs to do something similar to this, this post will help and give them ideas to figure it out on their own.
The point is that, as mbozzi said, you're already fixated on implementing a specific solution to a problem - having two constructors for a class - when, in fact, there may be a much better, completely different solution to the thing you're trying to achieve. When the language doesn't support well the thing you're trying to implement, it's often because what you're trying to implement is not the best way to achieve the thing you're trying to write code for.
It often indicates that there is a different design, that would be a much better way of doing what you want. If you told us what you're trying to achieve, maybe we could help you find that better solution, rather than giving you convoluted ways to implement a poorer one.
That said, the advice given you so far is spot-on: you have a design flaw in your thinking. You are giving your class the exact same data but expecting it to mean two different things? Confuddled design → confuddled behavior.