C ++: Сравнение указателей базовых и производных классов - PullRequest
10 голосов
/ 14 апреля 2011

Я хотел бы получить некоторую информацию о передовых практиках при сравнении указателей в таких случаях, как этот:

class Base {
};

class Derived
    : public Base {
};

Derived* d = new Derived;
Base* b = dynamic_cast<Base*>(d);

// When comparing the two pointers should I cast them
// to the same type or does it not even matter?
bool theSame = b == d;
// Or, bool theSame = dynamic_cast<Derived*>(b) == d?

Ответы [ 2 ]

5 голосов
/ 14 апреля 2011

Если вы хотите сравнить произвольные иерархии классов, лучше всего сделать их полиморфными и использовать dynamic_cast

class Base {
  virtual ~Base() { }
};

class Derived
    : public Base {
};

Derived* d = new Derived;
Base* b = dynamic_cast<Base*>(d);

// When comparing the two pointers should I cast them
// to the same type or does it not even matter?
bool theSame = dynamic_cast<void*>(b) == dynamic_cast<void*>(d);

Учтите, что иногда вы не можете использовать static_cast или неявное преобразование из производного в базовый класс:

struct A { };
struct B : A { };
struct C : A { };
struct D : B, C { };

A * a = ...;
D * d = ...;

/* static casting A to D would fail, because there are multiple A's for one D */
/* dynamic_cast<void*>(a) magically converts your a to the D pointer, no matter
 * what of the two A it points to.
 */

Если A виртуально наследуется, вы не можете сделать static_cast равным D.

5 голосов
/ 14 апреля 2011

Вы не требуете никакого приведения в вышеприведенном случае, простой Base* b = d; будет работать. Затем вы можете сравнить указатели, как вы сравниваете сейчас.

...