Вам это на самом деле не нужно, потому что вам не нужно захватывать уничтожение объекта. Вы заметите, что пример на этой странице Википедии содержит промежуточную сумму количества объектов данного типа, поэтому CRTP имеет две удобные функции:
- , поскольку это базовый класс, вызывается его деструктор (член также достигнет этого).
- , поскольку он основан на типе производного класса, для каждого класса, который наследуется от него, есть отдельный счетчик, включая разные классы в иерархии, если они используют множественное наследование, чтобы каждый включал свою собственную базу CRTP, без написания большого количества кода для каждый класс.
Если вам просто нужно уникальное значение для каждого члена отдельного класса, то, кроме безопасности потоков, вы можете сделать это следующим образом:
int get_id() {
static int counter = 0;
return ++counter;
}
class Address {
int addr;
public:
Address() : addr(get_id()) {}
};
Следуя примеру CRTP, вы можете использовать шаблон get_id
и использовать Address
в качестве аргумента, если у вас есть несколько классов для отслеживания, и вы хотите, чтобы у каждого из них было свое пространство идентификаторов.
И для этого варианта использования, если вы использовали CRTP, вы можете поместить элемент данных addr
в базовый класс шаблона, что является преимуществом, если у вас много классов, так как для каждого класса набирать меньше используя его:
template <typename Derived>
class unique_addr {
protected:
int addr;
unique_addr() : addr(get_id<Derived>()) {}
};
class Address : public unique_addr<Address> {
};
class OtherAddress : public unique_addr<OtherAddress> {
};