【问题标题】:Defining multiple functions with the same name using custom types使用自定义类型定义多个同名函数
【发布时间】:2020-10-14 12:53:49
【问题描述】:

我一直在玩 C++,但发现了一些我不太理解的东西:

typedef float degrees;
typedef float radians;

void my_func(degrees n);
void my_func(radians m);

像这样声明一个函数,我收到一个警告,该函数被重新声明,好像它们是相同的。这是否意味着,在查看函数定义时,编译器只看到内置类型而不关心自定义类型,并且由于它们是机器人浮点数,它只是认为它们是同一个函数?...

如果是这样,我该如何解决?我只需要制作不同的功能吗?

【问题讨论】:

  • 你可以看看 "strong typedef" (as BOOST_STRONG_TYPEDEF)
  • 您没有定义自定义类型,您使用不同的别名来定义相同类型的 float
  • 顺便说一句,在这里,我将使用静态构造函数 DegreeRadian 创建一个类 Angle

标签: c++ function-declaration custom-type


【解决方案1】:

另一种可能性是定义RadianDegree 类以从floats 进行显式转换,并对其进行隐式转换。

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 的函数,它会正常工作。


这个版本确实意味着,与typedefs 不同,您将无法编写类似的东西

Degree alpha = 30;
Degree beta = 60;
Degree gamma = alpha + beta; // 90 degrees

但是,如果需要,您还可以为每个类定义算术运算符,例如 operator+operator* 等。例如,您可能希望始终以 360 为模执行度数算术运算,以便 180 + 180 = 0

【讨论】:

    【解决方案2】:

    您可以定义类来处理这些问题。看看这个例子:

    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)
    }
    

    【讨论】:

      【解决方案3】:

      typedef 仅为现有类型创建一个新名称,因此在您的示例中,编译器将度数、弧度和浮点数关联为相同的数据类型。它们不是自定义类型,而只是预先存在的类型的新名称。

      【讨论】:

        【解决方案4】:

        问题是您没有使用 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();
        };
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-04-10
          • 1970-01-01
          • 2022-06-28
          • 1970-01-01
          相关资源
          最近更新 更多