I want to make something functionally similar to this:
class Base
{
public:
const int ClassID = 1;
}
class Derived1 : public Base
{
public:
const int ClassID = 2;
}
class Derived2 : public Base
{
public:
const int ClassID = 3;
}
But, obviously, you can't override variables. What would be the best way to achieve the same functionality?
(The context for this is a video game where there are different troops, overridden from the same parent "BaseTroop" class. I want each troop to have its own ID that can be retrieved from anywhere)
Thanks in advance!
CodePudding user response:
There is no way to change the default member initialiser in derived classes.
But, there is no need to rely on the default initialiser. You can provide an initialiser in the constructor:
struct Derived1 : Base
{
Derived1(): Base{2} {}
};
struct Derived2 : Base
{
Derived2(): Base{3} {}
};
CodePudding user response:
Add a virtual function, returning the ID. You can also have a static
variable or function returning the same ID, in case you want to get it without a class instance. You can also assign the IDs automatically, using CRTP:
#include <iostream>
struct BaseLow
{
virtual int GetId() const = 0;
virtual ~BaseLow() {}
};
namespace impl
{
int &GetIdCounter()
{
static int ret = 0;
return ret;
}
}
template <typename Derived>
struct Base : BaseLow
{
inline static const int id = impl::GetIdCounter() ;
int GetId() const override final
{
return id;
}
};
struct Derived1 : Base<Derived1> {};
struct Derived2 : Base<Derived2> {};
int main()
{
std::cout << Derived1::id << '\n'; // 0
std::cout << Derived2::id << '\n'; // 1
Derived1 d1;
Derived2 d2;
BaseLow *ptrs[] = {&d1, &d2};
for (BaseLow *ptr : ptrs)
std::cout << ptr->GetId() << '\n'; // 0, 1
}