Ew można całe liczenie wyciągnąć do osobnej klasy, która będzie liczyła id dla obiektów różnego typu:
template<typename T>
class counted_type {
static size_t counter;
protected:
counted_type(){}
static size_t next_id() {
return counter += 1;
}
public:
size_t id = next_id();
};
template<typename T>
size_t counted_type<T>::counter = 0;
Możemy sprawdzić to np. na "ludziach i owocach":
class person: public counted_type<person> {
using counted_type<person>::id;
string first_name, last_name;
public:
person(string const &fname, string const &lname):
first_name(fname), last_name(lname){}
string to_string() const {
return first_name + ", " + last_name + ", " + std::to_string(id);
}
};
class fruit: public counted_type<fruit> {
using counted_type<fruit>::id;
string kind;
public:
fruit(string const &kind): kind(kind){}
string to_string() const {
return kind + ", " + std::to_string(id);
}
};
oraz następujących danych:
person people[] = {
person("John", "Travolta"),
person("Rocky", "Balboa"),
person("Rick", "Grimes")
};
fruit fruits[] = {
fruit("banana"),
fruit("apple"),
fruit("peach")
};
http://ideone.com/S2Yc8N
John, Travolta, 1
Rocky, Balboa, 2
Rick, Grimes, 3
banana, 1
apple, 2
peach, 3
Ewentualnie możemy całość za drobną zmianą przerobić na wersję nieinwazyjną:
template<typename T>
class type_counter {
static size_t counter;
protected:
static size_t next_id() {
return counter += 1;
}
public:
type_counter(){}
size_t id = next_id();
};
template<typename T>
size_t type_counter<T>::counter = 0;
wnet nasz person
będzie wyglądał tak:
class person {
const type_counter<person> counter;
string first_name, last_name;
public:
person(string const &fname, string const &lname):
first_name(fname), last_name(lname){}
string to_string() const {
return first_name + ", " + last_name + ", " + std::to_string(counter.id);
}
};
http://melpon.org/wandbox/permlink/3qBbQYYmxN81J3uz