Как сделать числа, передаваемые в функцию, безопасными для типов? - PullRequest
0 голосов
/ 27 марта 2020

У меня были функции, которые должны были принимать идентификационный номер (целое число), но я заметил, что случайно передавал идентификационные номера разных вещей, что нарушало мою программу. Поэтому я попытался сделать что-то вроде следующего, чтобы сделать его безопасным для типов:

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
}

Единственная причина, по которой я создал классы для хранения чисел, состояла в том, чтобы предотвратить передачу неправильного идентификационного номера. И причина, по которой я использовал наследование от Number, заключается в том, что любые классы, такие как Dog и Cat, можно рассматривать как идентификационный номер (назначенный).

Какой самый простой способ отправить идентификационные номера в функцию, но убедиться, что вы отправляете ей правильные идентификаторы? Я не уверен, что перечислимые классы являются опцией, потому что идентификаторы задаются во время выполнения.

Также я обнаружил, что:

Все перегруженные операторы, кроме присваивания (operator =), наследуются производные классы.

Является ли причиной того, что оператор = является единственной перегрузкой оператора, не унаследовано то, что это считалось слишком рискованным, учитывая, что у производных классов могут быть дополнительные члены?

1 Ответ

1 голос
/ 27 марта 2020

Что вы можете сделать, это использовать тег для своего номера

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 своего рода тег. Это гарантирует, что Number<Tag1> не относится к типу Number<Tag2>

Однако в общей архитектуре я бы не рекомендовал использовать operator = on int, поскольку вы теряете немного безопасности типов .

Например, в этом коде:

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

Это не так хорошо, и я рекомендую вам использовать только такую ​​вещь:

DogId id = DogId{anInteger}

и продолжайте использовать шаблон Number класс, который мы видели выше

Примечание

  1. Ваша operator= функция должна возвращать ссылку на текущий объект, а не int.
  2. Опасно не возвращать что-либо из функции, которая должна что-то возвращать. В C это опасно, в C ++ это неопределенное поведение.
...