Sto cercando di scoprire la classe più derivata di un oggetto, all'interno di un costruttore di una delle classi nel suo albero di ereditarietà. Ho passato diverse ore su questo ora e sono in perdita per come altro posso farlo o perché non ha senso. Sembra avere perfettamente senso, eppure si rifiuta di lavorare. Ho trovato numerose pagine su RTTI e praticamente non sono stato in nessun posto con loro. Continuerò a spiegare dopo il mio caso di test e il suo output.Il puntatore "questo" è abilitato per RTTI?
La fonte:
#include <iostream>
#include <typeinfo>
#include <string>
class A
{
public:
A(std::string foo);
virtual void bar(A* a) = 0;
};
class B : public A
{
public:
B();
virtual void bar(A* a);
};
A::A(std::string foo)
{
std::cout << "type as passed to A constructor: " << foo << " (" << this << ")" << std::endl;
std::cout << "type as determined in A constructor: " << typeid(*this).name() << " (" << this << ")" << std::endl;
}
B::B() : A(typeid(*this).name())
{
A* a = (A*)this;
std::cout << "type as determined in B constructor: " << typeid(*a).name() << " (" << this << ")" << std::endl;
this->bar(this);
}
void B::bar(A* a)
{
std::cout << "type as determined in bar: " << typeid(*a).name() << " (" << a << ")" << std::endl;
}
int main()
{
B b;
b.bar(&b);
return 0;
}
L'uscita (in g ++):
type as passed to A constructor: 1B (0x7fff5fbff910)
type as determined in A constructor: 1A (0x7fff5fbff910)
type as determined in B constructor: 1B (0x7fff5fbff910)
type as determined in bar: 1B (0x7fff5fbff910)
type as determined in bar: 1B (0x7fff5fbff910)
sto cercando di ottenere la seconda riga dell'output dire "1B" invece di "1A" . Il RTTI è stato rimosso da "questo" per qualche motivo che non riesco ancora a immaginare? In che modo non infrange l'idea delle funzioni virtuali? (L'ho implementato con funzioni virtuali fino a quando ho scoperto che stavo reimplementando parte di RTTI, che non avevo mai conosciuto prima.) Come mostra l'output, posso farlo funzionare se evito di usare "this", ma il bisogno farlo sembrerebbe una rottura del design.
perché stai cercando di rilevare il tipo? non è buono questo suona come una soluzione (imperfetta) tentata a qualcos'altro, qual'è qualcos'altro? –
Alf, ho std :: mappe di tipi (std :: stringhe, in questo caso) per oggetti, con ogni tipo che ha un oggetto unico all'interno della mappa. Ogni istanza di una determinata classe ha una propria mappa, per consentire di aggiungere facilmente nuovi oggetti a questi oggetti core e successivamente recuperati per tipo. (Lo stavo facendo con i const e una rete di metodi virtuali prima che sapessi di RTTI, con un errore equivalente per lo stesso motivo.) – Grault