I had functions that were supposed to take an ID number (an int), but I noticed that I was accidentally passing the ID numbers of different things, which broke my program. So I tried to do something like the following to make it type-safe:
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
}
The only reason I created classes to hold the numbers was to prevent passing the wrong ID number. And the reason I used inheritance from Number is so that any classes like Dog and Cat could be treated like an ID number (assigned to).
What's the cleanest way to be able to send ID numbers to a function but ensure that you're sending the right IDs to it? I'm not sure enum classes are an option because IDs are given at runtime.
Also I found out that:
All overloaded operators except assignment (operator=) are inherited by derived classes.
Is the reason for why the operator = is the only operator overload not inherited that it was considered too risky given that derived classes may have extra members?
What you can do is to use a Tag for your Number
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
}
The idea is to give a kind of tag to your Number
class. Doing so will ensure that Number<Tag1>
is not of the same type of Number<Tag2>
However, in a general architecture, I would not recommand using an operator= on int, because you lose a bit of type safety.
For example, in this code:
void f(int accountId) {DogId id = accountId;}
It is not that good and I recommand you to only use such a thing :
DogId id = DogId{anInteger}
and to continue to use the template Number
class we saw above
operator=
function must return a reference on the current object, not a int.