如何使传递给函数的数字类型安全?

How can I make numbers passed to a function type-safe?

我有一些函数本应采用 ID 号(整数),但我注意到我不小心传递了不同事物的 ID 号,这破坏了我的程序。所以我尝试做类似下面的事情来使其类型安全:

struct Number
{
    int ID;
    int operator =(const int& rhs) { ID = rhs; }
}

struct DogID : Number { }
struct CatID : Number { }

void functionTakingDogID(DogID ID) { }
void functionTakingCatID(CatID ID) { }

int main()
{
     DogID dogID;
     dogID = 5; // But the = operator overload isn't inherited
}

我创建 类 来保存号码的唯一原因是为了防止传递错误的 ID 号码。我使用从 Number 继承的原因是这样任何 类 像 Dog 和 Cat 都可以被视为 ID 号(分配给)。

能够将 ID 号发送到函数但确保向其发送正确 ID 的最简洁方法是什么?我不确定枚举 类 是否是一个选项,因为 ID 是在运行时给出的。

我还发现:

All overloaded operators except assignment (operator=) are inherited by derived classes.

运算符 = 是唯一未继承的运算符重载的原因是因为派生的 类 可能有额外的成员,它被认为风险太大了吗?

您可以为您的号码使用标签

template<typename Tag>
struct Number
{
    int ID;
    Number &operator =(int rhs) { ID = rhs; return *this;}
};

using DogID = Number<struct DogIdTag>;
using CatID = Number<struct CatIdTag>;

int main()
{
     DogID dogID;
     dogID = 5; // But the = operator overload isn't inherited
}

这个想法是给你的 Number class 一种标签。这样做将确保 Number<Tag1>Number<Tag2>

的类型不同

但是,在一般架构中,我不建议在 int 上使用 operator=,因为这样会失去一点类型安全性。

例如,在这段代码中:

void f(int accountId) {DogId id = accountId;}

不是很好,我建议你只使用这样的东西:

DogId id = DogId{anInteger}

并继续使用我们在上面看到的模板 Number class

备注

  1. 您的 operator= 函数必须 return 当前对象的引用,而不是 int。
  2. 不从需要 return 的函数中 return 某些东西是危险的。在 C 中是危险的,在 C++ 中是未定义的行为。