Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何使传递给函数类型的数字安全?_C++_Type Safety - Fatal编程技术网

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

C++ 如何使传递给函数类型的数字安全?,c++,type-safety,C++,Type Safety,我有一些函数应该使用ID号(int),但我注意到我不小心传递了不同事物的ID号,这破坏了我的程序。因此,我尝试执行以下操作以确保其类型安全: struct Number { int ID; int operator =(const int& rhs) { ID = rhs; } } struct DogID : Number { } struct CatID : Number { } void functionTakingDogID(DogID ID) { } voi

我有一些函数应该使用ID号(int),但我注意到我不小心传递了不同事物的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是在运行时给出的

我还发现:

除赋值(运算符=)之外的所有重载运算符都由派生类继承


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

您可以做的是使用标记作为编号

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
}
这不太好,我建议你只使用这样的东西:

DogId id = DogId{anInteger}
继续使用我们在上面看到的模板
Number

  • 运算符=
    函数必须返回当前对象的引用,而不是int
  • 不从需要返回内容的函数返回内容是危险的。在C中,它是危险的,在C++中是一个未定义的行为。
    BOOST\u STRONG\u TYPEDEF
    适用于原语。我只是想问一下,你会在一秒钟内找到一个复制品吗?或者你需要
    操作符=
    ?也许您可以在每个派生类的构造函数中传递ID,并在其中进行验证。@Yksisarvinen严格来说,运算符=重载是不必要的,我可以改为执行dogID.ID=5而不是dogID=5。我只是重载了它,所以我可以把dogID当作一个数字,就像我在使它成为类型安全之前所做的那样。谢谢,这个解决方案看起来不错。而且不需要使用boost之类的外部库。
    DogId id = DogId{anInteger}