当 declarations/parameters 相同时如何重载 constructors/functions?

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

我想创建一个 class 来管理矩阵,但我遇到了构造函数问题。 目的是找到调用 Matrix 对象的构造函数的最短方法,知道某些构造函数具有与保持清晰相同的 header。 这是我试图得到的想法:

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

在这里,所有的参数都是 floats 所以我不能重载构造函数,我唯一看到的是使用模板,但仅适用于那些特殊情况,然后我不知道该怎么做。

解决方案

最后我决定像这样做一个摘要class :

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);

                // ...
        }

        // ...
}

所有都将定义到 _Mat 中,而另一个 class 将只对它们的构造函数有用

最后,我们可以这样调用构造函数了:

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

您有以下选择:

  1. 在构造函数中引入不同类型的不同虚拟参数来区分重载。它很老套,我不推荐它。

  2. 使用继承。创建不同的子类,其中每个子类都以其构造函数提供的功能命名。

  3. 将您的构造函数设为私有并引入 public static 工厂方法,这些方法具有漂亮而长的名称,可以清楚地表明它们的作用。 (没有重载。)

就我个人而言,我会选择第三种选择。

您正在寻找标签调度。您可以在标准库中看到它的使用,例如在 std::pair's constructor.

的重载中

您只需声明一个 "tag" 结构,用于指导重载解析:

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

然后重载你的构造函数:

struct Matrix {

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

    // ...
};

那么你可以这样使用它:

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

您可以保持简单并使用静态成员函数:

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);