Как перегрузить конструкторы / функции, когда объявления / параметры совпадают?

Я хотел бы создать класс для управления матрицами, и я столкнулся с проблемой с конструктором.
Цель состоит в том, чтобы найти кратчайший способ вызвать конструктор объекта 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
...

Здесь все параметры floatТак что я не могу перегружать конструктор, я вижу только использование шаблонов, но только для тех особых случаев, тогда я не знаю, что делать.

Решение

В конце концов я решил создать абстрактный класс следующим образом:

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

3

Решение

Вы можете сделать это простым и использовать статические функции-члены:

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

Другие решения

Ты ищешь диспетчеризация тегов. Вы можете видеть, что он используется в стандартной библиотеке, например, в перегрузках std::pairконструктор.

Вам просто нужно объявить структуру «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};
}
4

У вас есть следующие варианты:

  1. Ввести разные фиктивные параметры разных типов в конструкторы, чтобы различать перегрузки. Это хак, я бы не советовал.

  2. Используйте наследство. Создайте разные подклассы, где каждый из них будет назван в соответствии с функциональностью, предоставляемой его конструктором.

  3. Сделайте свой конструктор частным и представьте public static фабричные методы, которые имеют красивые и длинные имена, которые четко указывают на то, что они делают. (Без перегрузки.)

Лично я бы выбрал третий вариант.

2
По вопросам рекламы ammmcru@yandex.ru
Adblock
detector