3

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

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 _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,另一个类将对其构造函数有用

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

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

3 回答 3

4

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

您只需声明一个“标记”结构,用于指导重载解决方案:

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};
}
于 2017-05-28T22:21:30.207 回答
4

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

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);
于 2017-05-28T22:30:49.510 回答
2

您有以下选择:

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

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

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

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

于 2017-05-28T22:18:42.503 回答