问题描述
我一直在玩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)
}
,
另一种可能性是定义Radian
和Degree
类,以从float
进行显式转换,并对其进行隐式转换。
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
不同的是,您将无法编写类似的内容
Degree alpha = 30;
Degree beta = 60;
Degree gamma = alpha + beta; // 90 degrees
但是,如果需要,还可以为每个类定义算术运算符,例如operator+
,operator*
等。例如,您可能希望始终执行360
模的度算术运算,以使180 + 180 = 0
。
typedef
仅为现有类型创建一个新名称,因此在您的示例中,编译器将度,弧度和浮点数关联为相同的数据类型。它们不是说的自定义类型,而只是现有类型的新名称。
问题是您没有使用2个不同的类型,而同一类型只使用了2个不同的别名,因此对于编译器,它是相同的功能。
现在解决方法很多:
第一个可以被声明为2个不同的类,仅具有float类型的属性,如果您希望隐式转换为double的浮点,请重新实现该转换:
class Radian{
public:
float angle;
Radian(){};
operator float() { return angle; }
};
另一个解决方案可以声明两个不同的函数名称,例如:
void my_func_deg(degrees n);
void my_func_rad(radians m);
或使用内部函数创建2个不同的类:
class Radian{
public:
double angle;
Radian(){};
void my_func();
};