当 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
...
在这里,所有的参数都是 float
s 所以我不能重载构造函数,我唯一看到的是使用模板,但仅适用于那些特殊情况,然后我不知道该怎么做。
解决方案
最后我决定像这样做一个摘要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);
// ...
您有以下选择:
在构造函数中引入不同类型的不同虚拟参数来区分重载。它很老套,我不推荐它。
使用继承。创建不同的子类,其中每个子类都以其构造函数提供的功能命名。
将您的构造函数设为私有并引入 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);
我想创建一个 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
...
在这里,所有的参数都是 float
s 所以我不能重载构造函数,我唯一看到的是使用模板,但仅适用于那些特殊情况,然后我不知道该怎么做。
解决方案
最后我决定像这样做一个摘要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);
// ...
您有以下选择:
在构造函数中引入不同类型的不同虚拟参数来区分重载。它很老套,我不推荐它。
使用继承。创建不同的子类,其中每个子类都以其构造函数提供的功能命名。
将您的构造函数设为私有并引入
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);