Видя, к какому классу относится объект - PullRequest
0 голосов
/ 13 декабря 2010

Если у меня есть указатель на базовый класс A в C ++, как бы я мог сказать в своем коде, что указатель на производный класс B или C?

Ответы [ 3 ]

6 голосов
/ 13 декабря 2010

Предполагая, что базовый класс A является полиморфным (то есть имеет хотя бы одну виртуальную функцию), вы можете использовать dynamic_cast. Учитывая A* ap;:

if (B* bp = dynamic_cast<B*>(ap)) {
    // the object is a B
}
else if (C* cp = dynamic_cast<C*>(ap)) {
    // the object is a C
}
2 голосов
/ 13 декабря 2010

Как правило, вам не нужно знать:

struct A {
    virtual int generate_foo() = 0;
};

struct B : A {
    int generate_foo() { return 42; }
};

struct C : A {
    i_;
    C(int i) : i_(i) { }
    int generate_foo() { return i_++; }
};

Если у вас есть A*, вы (1) знаете, что у него есть метод generate_foo(), и (2) знаете, что generate_foo() сгенерирует подходящее foo для любого объекта, который у вас действительно есть.В общем, этого должно быть достаточно, и вы должны иметь возможность отслеживать, когда у вас есть A*.

С философской точки зрения дизайнеры C ++ потратили годы, пытаясь избежать добавления информации о типе среды выполненияпотому что это слишком легко используется неправильно.Тем не менее, они в конечном итоге решили, что находятся не на том конце проигравшей битвы, и добавили dynamic_cast и typeinfo().C ++ 0x добавит больше.

1 голос
/ 13 декабря 2010

Другой подход,

if ( typeid(*pBase) == typeid(A))
{
      cout << "A" << endl;
}
else if ( typeid(*pBase) == typeid(B))
{
      cout << "B" << endl;
}
else if ( typeid(*pBase) == typeid(C))
{
      cout << "C" << endl;
}
else
{
      cout << "something else" <<endl;
}

Но я бы предпочел подход Джеймса, потому что, используя его, вы не только определяете тип , , но у вас также есть тип-приведенный экземпляр для работы с , потом!

...