Ok, quindi mi sono imbattuto in una ... risposta un po 'accettabile. Ho pensato che non avrebbe funzionato se le sottoclassi non avessero assolutamente la conoscenza reciproca (voglio dire, stiamo parlando di programmazione piuttosto funzionale ...).
Ecco una soluzione per questo. Non è sicuramente la soluzione che vorrei; tuttavia, è un inizio. Ho forzato tutti gli oggetti a utilizzare un modulo di CRTP, ma uno che utilizza più di un formato di elenco collegato. In questo modo, i nostri sottoclassi devono provenire da un oggetto <> basati su modelli da:
A: si e B: il più recente sottoclasse definita in precedenza
ecco il mio codice per questo (io uso un modello da <type_traits>
una volta, solo una nota)
template <typename T> //SFINAE check for the existance of subclasscount static member
struct has_subclasscount
{
template <typename U>
static typename std::enable_if<sizeof(U::subclasscount) != 0, int>::type test(int);
template <typename U>
static char test(...);
static const bool result = (sizeof(test<T>(0)) == sizeof(int))?(true):(false);
};
template <bool res, typename T>
struct return_subclasscount //the value to return is 0 if false
{
static const int result = 0;
};
template <typename T>
struct return_subclasscount<true, T> //returns subclasscount only if the first parameter is true
{
static const int result = T::subclasscount;
};
template <typename T> //combines return_subclasscount and has_subclasscount
struct get_subclasscount
{
static const int result = return_subclasscount<has_subclasscount<T>::result, T>::result;
};
template <typename This, typename Prev>
class Object
{
public:
static const int subclasscount = 1 + get_subclasscount<Prev>::result; //the subclass count
};
class sub1 : public Object<sub1, int>
{
};
class sub2 : public Object<sub2, sub1>
{
};
class sub3 : public Object<sub3, sub2>
{
};
Queste ultime 3 classi vuote sono le sottoclassi che stiamo contando. Questo è il nostro file di intestazione. Nel nostro file cpp principale, abbiamo:
int main() {
std::cout << sub3::subclasscount;
char c;
std::cin >> c;
}
L'esecuzione, otteniamo una semplice uscita di:
che conferma che ha funzionato. Ora, alcuni degli aspetti negativi di questa soluzione è:
- Dobbiamo sapere quello che la nostra ultima sottoclasse definiti era, prima di aggiungere su.
- Dobbiamo stare al passo con qualsiasi parte usiamo il contatore di sottoclasse, modificandolo sempre dall'ultima sottoclasse nell'elenco (questo può essere evitato usando una sottoclasse consistente "endoflist", che invece andrebbe mantenuta)
I lati positivi, tuttavia, includono il fatto che non è necessario mantenere alcuna delle sottoclassi precedentemente definite.Tuttavia, considero questa risposta più un "punto di partenza" che una "soluzione finale"; forse qualcosa che può essere ampliato?
(anche, questo può essere facilmente abusato per fare una forma di struttura ad albero, dove subclasscount
sarebbe in realtà rappresentano la profondità di un dato nodo nell'albero)
Qualcuno ha qualche idea da qui?
Giusto per notare, sto lavorando per risolvere questo problema, me stesso. Ti sto solo chiedendo ragazzi nel caso non lo faccia mai, o lo fai prima. – Serge
Dovrebbe essere possibile - vuoi avere un contatore per le sottoclassi a ogni livello gerarchico o solo l'intero numero di sottoclassi di oggetti? – duselbaer
Solo le sottoclassi di quel livello; Non mi aspetto un'erarchia. – Serge