Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++: Comparing pointers of base and derived classes

I'd like some information about best practices when comparing pointers in cases such as this one:

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?
like image 305
Paul Manta Avatar asked Apr 14 '11 11:04

Paul Manta


People also ask

What is the difference between a base class pointer and a derived class pointer?

Explanation: A base class pointer can point to a derived class object, but we can only access base class member or virtual functions using the base class pointer because object slicing happens when a derived class object is assigned to a base class object.

What is the difference between base class and derived class?

1. A base class is an existing class from which the other classes are derived and inherit the methods and properties. A derived class is a class that is constructed from a base class or an existing class.

Can pointers reference objects of different base types?

A pointer reference is polymorphic, since it can reference objects of different dynamic type.

Can a derived pointer point to a base class?

A derived pointer cannot be assigned a pointer to a base type without casting simply because it cannot tell if the base pointer is of the Derived type or one of its children.


1 Answers

If you want to compare arbitrary class hierarchies, the safe bet is to make them polymorphic and use 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);

Consider that sometimes you cannot use static_cast or implicit conversion from a derived to a base class:

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.
 */

If A is inherited virtually, you can't static_cast to a D either.

like image 178
Johannes Schaub - litb Avatar answered Oct 16 '22 17:10

Johannes Schaub - litb