2013-04-21 17 views
7

Załóżmy, że mam abstrakcyjną klasę podstawową Parent i podklas Child1 i Child2. Jeśli mam funkcję, która bierze Parent *, czy istnieje sposób (być może z RTTI?) Do określenia w czasie wykonywania, czy to Child1 *, czy Child2 *, że funkcja faktycznie została odebrana?Identyfikacja podklasy, której przypisano wskaźnik do jej klasy bazowej?

Moje dotychczasowe doświadczenie z RTTI było takie, że gdy foo jest rodzicem *, typeid (foo) zwraca typid (Parent *) niezależnie od klasy potomnej, której członkiem jest foo.

+2

"Parent" to zawsze "Parent". To jest * nigdy * "Dziecko *". To, o co pytasz, to "jaki jest typ rzeczy, na którą wskazuje". –

+0

Kerrek SB: Wczoraj dałem ci zimne ramię, ale kiedy dotarłem do właściwego programowania, twój komentarz był prawdopodobnie bardziej wartościowy niż cokolwiek innego na stronie. Przepraszam za to ... – ExOttoyuhr

Odpowiedz

5

Trzeba spojrzeć na typeid z dereferencjonowane wskaźnik, a nie sam wskaźnik; Tj., Typeid (* foo), a nie typeid (foo). Pytanie o wskaźnik dereferencji da ci dynamiczny typ; pytanie o sam wskaźnik sprawi, że zauważysz statyczny typ.

+0

To brzmi jak dokładniejsze dopasowanie do tego, czego szukałem, niż tworzenie wielu wskaźników podprzedziałowych byłoby ... – ExOttoyuhr

+0

Warto wspomnieć, że 'typeid (* foo)' zwróci tylko poprawny typ środowiska wykonawczego (np. Child1' zamiast "Parent"), jeśli klasa nadrzędna ma co najmniej jedną metodę wirtualną. – ApproachingDarknessFish

2

Sure:

BaseClass *bptr = // whatever, pointer to base class 
SubclassOne *safe_ptr_one = dynamic_cast<SubclassOne *>(bptr); 
if (safe_ptr_one != nullptr) { 
    // Instance of SubclassOne 
} else { 
    // not an instance of SubclassOne, try the other one 
    SubclassTwo *safe_ptr_two = dynamic_cast<SubclassTwo *>(bptr); 
    if (safe_ptr_two != nullptr) { 
     // Instance of SubclassTwo 
    } else { 
     // it wasn't either one :'(
    } 
} 
+0

Miło - nie wiedziałem, że dynamic_cast może to zrobić! (Ale potem, dlatego spytałem.) – ExOttoyuhr

+0

@ExOttoyuhr Nie ma za co. A tak, udało mi się udzielić odpowiedzi przed Andym Prowlem! –

5

Można użyć std::dynamic_cast do tego.

Parent* ptr = new Child1(); 
if(dynamic_cast<Child1*>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(dynamic_cast<Child2*>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 

Także jeśli używasz inteligentne kursory, jak std::shared_ptr, można sprawdzić to w ten sposób:

std::shared_ptr<Parent> ptr(new Child1()); 
if(std::dynamic_pointer_cast<Child1>(ptr) != nullptr) { 
    // ptr is object of Child1 class 
} else if(std::dynamic_pointer_cast<Child2>(ptr) != nullptr) { 
    // ptr is object of Child2 class 
} 
Powiązane problemy