使用自定义类型定义具有相同名称的多个功能

问题描述

我一直在玩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)
}
,

另一种可能性是定义RadianDegree类,以从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的隐式转换意味着您可以将类型为RadianDegree的变量传递给期望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();
};