使用自定义类型定义多个具有相同名称的函数
Defining multiple functions with the same name using custom types
我一直在研究 C++,但我注意到一些我不太理解的东西:
typedef float degrees;
typedef float radians;
void my_func(degrees n);
void my_func(radians m);
像这样声明一个函数,我收到一条警告,该函数被重新声明,就好像它们是相同的一样。这是否意味着,在查看函数定义时,编译器只看到内置类型而不关心自定义类型,并且由于它们是 bot float,它只是将它们视为相同的函数?...
如果是这种情况,我该如何解决这个问题?我只需要做一个不同的功能吗?
您可以定义类来处理这些问题。看这个例子:
class Degree{
public:
double angle;
Degree(){}
void my_func(){
// do some job
}
};
class Radian{
public:
double angle;
Radian(){}
void my_func(){
// do some job
}
};
int main(){
Degree deg;
Radian rad;
deg.my_func();
rad.my_func();
}
现在他们在各自的职能中执行不同的任务。
或者如果你不想创建对象,你可以在这些 类.
中创建一个静态函数
class Radian{
public:
static void my_func(float radian){
// do some job
}
};
typedef float degrees;
typedef float radians;
int main(){
radians rad;
Radian::my_func(rad)
}
typedef
仅为现有类型创建一个新名称,因此在您的示例中,编译器将度数、弧度和浮点数关联为相同的数据类型。他们不是说自定义类型,而只是 pre-existing 类型的新名称。
问题是您没有使用 2 种不同的类型,而是对同一类型使用了 2 个不同的别名,因此对于编译器来说,它是相同的函数。
现在有多种解决方法:
第一个可以声明 2 个不同的 类,只有一个 float 类型的属性,如果你想隐式转换为 double 的 float,请按这种方式重新实现转换:
class Radian{
public:
float angle;
Radian(){};
operator float() { return angle; }
};
另一个解决方案可以声明 2 个不同的函数名称,例如:
void my_func_deg(degrees n);
void my_func_rad(radians m);
或使用内部函数创建 2 个不同的 类:
class Radian{
public:
double angle;
Radian(){};
void my_func();
};
另一种可能性是定义 Radian
和 Degree
classes 以从 float
s 进行显式转换并隐式转换它们。
class Radian{
float m_value;
public:
explicit Radian(float t_value) : m_value(t_value) { }
operator float() const { return m_value; }
};
class Degree{
float m_value;
public:
explicit Degree(float t_value) : m_value(t_value) { }
operator float() const { return m_value; }
};
void my_func(Radian r);
void my_func(Degree d);
my_func(Radian(10)); // calls the Radian overload
my_func(Degree(10)); // calls the Degree overload
my_func(10); // Doesn't call either because both ctors are explicit
到 float
的隐式转换意味着您可以将 Radian
或 Degree
类型的变量传递给需要 float
的函数,它就会正常工作。
这个版本确实意味着,与 typedef
s 不同,您将无法编写
Degree alpha = 30;
Degree beta = 60;
Degree gamma = alpha + beta; // 90 degrees
但是,如果需要,您也可以为每个 class 定义算术运算符,例如 operator+
、operator*
等。例如,您可能希望始终以 360
为模执行度数算术,以便 180 + 180 = 0
.
我一直在研究 C++,但我注意到一些我不太理解的东西:
typedef float degrees;
typedef float radians;
void my_func(degrees n);
void my_func(radians m);
像这样声明一个函数,我收到一条警告,该函数被重新声明,就好像它们是相同的一样。这是否意味着,在查看函数定义时,编译器只看到内置类型而不关心自定义类型,并且由于它们是 bot float,它只是将它们视为相同的函数?...
如果是这种情况,我该如何解决这个问题?我只需要做一个不同的功能吗?
您可以定义类来处理这些问题。看这个例子:
class Degree{
public:
double angle;
Degree(){}
void my_func(){
// do some job
}
};
class Radian{
public:
double angle;
Radian(){}
void my_func(){
// do some job
}
};
int main(){
Degree deg;
Radian rad;
deg.my_func();
rad.my_func();
}
现在他们在各自的职能中执行不同的任务。
或者如果你不想创建对象,你可以在这些 类.
中创建一个静态函数class Radian{
public:
static void my_func(float radian){
// do some job
}
};
typedef float degrees;
typedef float radians;
int main(){
radians rad;
Radian::my_func(rad)
}
typedef
仅为现有类型创建一个新名称,因此在您的示例中,编译器将度数、弧度和浮点数关联为相同的数据类型。他们不是说自定义类型,而只是 pre-existing 类型的新名称。
问题是您没有使用 2 种不同的类型,而是对同一类型使用了 2 个不同的别名,因此对于编译器来说,它是相同的函数。
现在有多种解决方法:
第一个可以声明 2 个不同的 类,只有一个 float 类型的属性,如果你想隐式转换为 double 的 float,请按这种方式重新实现转换:
class Radian{
public:
float angle;
Radian(){};
operator float() { return angle; }
};
另一个解决方案可以声明 2 个不同的函数名称,例如:
void my_func_deg(degrees n);
void my_func_rad(radians m);
或使用内部函数创建 2 个不同的 类:
class Radian{
public:
double angle;
Radian(){};
void my_func();
};
另一种可能性是定义 Radian
和 Degree
classes 以从 float
s 进行显式转换并隐式转换它们。
class Radian{
float m_value;
public:
explicit Radian(float t_value) : m_value(t_value) { }
operator float() const { return m_value; }
};
class Degree{
float m_value;
public:
explicit Degree(float t_value) : m_value(t_value) { }
operator float() const { return m_value; }
};
void my_func(Radian r);
void my_func(Degree d);
my_func(Radian(10)); // calls the Radian overload
my_func(Degree(10)); // calls the Degree overload
my_func(10); // Doesn't call either because both ctors are explicit
到 float
的隐式转换意味着您可以将 Radian
或 Degree
类型的变量传递给需要 float
的函数,它就会正常工作。
这个版本确实意味着,与 typedef
s 不同,您将无法编写
Degree alpha = 30;
Degree beta = 60;
Degree gamma = alpha + beta; // 90 degrees
但是,如果需要,您也可以为每个 class 定义算术运算符,例如 operator+
、operator*
等。例如,您可能希望始终以 360
为模执行度数算术,以便 180 + 180 = 0
.