How to overload constructors / functions when declarations / parameters are the same?

I would like to create a class to manage matrices and I am facing a constructor problem. The goal is to find the shortest way to call the constructor of the Matrix object, knowing that some of the constructors have the same title, which remains clear. This is the idea of ​​what I am trying to get:

Matrix id; // create identity matrix
Matrix scale(x, y, z); // create directly a scale matrix
Matrix translation(x, y, z) // create a translation matrix
...

      

All the parameters are here float

, so I can't overload the constructor, the only thing I see is to use templates, but only for these special cases, then I don't know what to do.

Decision

Finally, I decided to make an abstract class like this:

class _Mat
{
    public :
        virtual ~_Mat(void) = 0;

        // ...
}

class Mat : public _Mat
{
    public :
        Mat(void);
        virtual ~Mat(void);

        class Scale : public _Mat
        {
            public :
                Scale(float x, float y, float z);
                vitual ~Scale(void);

                // ...
        }

        // ...
}

      

Everything will be defined in _Mat

, and another class will only be useful for their constructor (s)

Finally, we can call constructors like this:

Mat id;
Mat::Scale scale(2, 2, 2);
// ...

      

+3


source to share


3 answers


You can keep it simple and use static member functions:



struct Matrix
{
    // ...

    static Matrix Translate(float x, float y, float z) {/*...*/}
    static Matrix Scale(float x, float y, float z) {/*...*/}
};

// ...

Matrix m = Matrix::Scale(1,2,3);

      

+4


source


You are looking for tag posting. You can see that it is used in the standard library, for example in std::pair

constructor
overloads .

You just need to declare a "tag" structure that is used to specify the overload resolution:

struct translation_matrix_tag_t {} static translation_matrix_tag;
struct scale_matrix_tag_t {} static scale_matrix_tag;

      

And then overload your constructors:



struct Matrix {

    Matrix(translation_matrix_tag_t, float, float, float);
    Matrix(scale_matrix_tag_t, float, float, float);

    // ...
};

      

Then you can use it like this:

void foo() {
    Matrix m1{translation_matrix_tag, x, y, z};
    Matrix m2{scale_matrix_tag, x, y, z};
}

      

+4


source


You have the following options:

  • By introducing different dummy parameters of different types in the constructors to differentiate between overloads. It is hacks, I would not recommend it.

  • Use inheritance. Create different subclasses, each named after the functionality provided by its constructor.

  • Make your constructor private and introduce public static

    factory methods that have nice and long names that clearly indicate what they do. (No overload.)

Personally, I would go with the third choice.

+2


source







All Articles