Implementing operator< on abstract base class - c++

I have a type hierarchy, and I'm not sure of a clean / good way to implement operator< and operator==.
Essentially, I already have this:
class Parent {
public:
virtual ~Parent() {}
};
class A : public Parent { int data; };
class B : public Parent { double data; };
class C : public Parent { std::string data; };
bool operator==(A const & lhs, A const & rhs) { return lhs.data == rhs.data; }
bool operator< (A const & lhs, A const & rhs) { return lhs.data < rhs.data; }
bool operator==(B const & lhs, B const & rhs) { return lhs.data == rhs.data; }
bool operator< (B const & lhs, B const & rhs) { return lhs.data < rhs.data; }
bool operator==(C const & lhs, C const & rhs) { return lhs.data == rhs.data; }
bool operator< (C const & lhs, C const & rhs) { return lhs.data < rhs.data; }
What I'd like to implement as well, is this:
bool operator==(Parent const & lhs, Parent const & rhs) { ... }
bool operator< (Parent const & lhs, Parent const & rhs) { ... }
I've currently implemented it by doing:
bool operator==(Parent const & lhs, Parent const & rhs) {
try {
return dynamic_cast<A const &>(lhs) == dynamic_cast<A const &>(rhs);
} catch(std::bad_cast const & e) {
}
try {
return dynamic_cast<B const &>(lhs) == dynamic_cast<B const &>(rhs);
} catch(std::bad_cast const & e) {
}
try {
return dynamic_cast<C const &>(lhs) == dynamic_cast<C const &>(rhs);
} catch(std::bad_cast const & e) {
}
assert(typeid(lhs) != typeid(rhs));
return false;
}
But this just seems awful. Is there a cleaner way of going about this?

For comparisons of complex types, you may find Double Dispatch useful.
If your types are very simple, it is sometimes effective to roll them all into one. In the example of 3 unsigned variants, it would likely be better to just use one type to accommodate all sizes, and to avoid dynamic dispatch and more complicated graphs of types.
Applied to original question; where A, B, and C all used unsigned types:
well, one quick and dirty approach would be:
class Parent {
protected:
virtual ~Parent() {}
public:
bool operator<(const Parent& pOther) const {
return this->as_uint64() < pOther.as_uint64();
}
// ...
private:
// using a type which accommodates all values
virtual uint64_t as_uint64() const = 0;
};
and then deriving from Parent would take the form:
class A : public Parent {
// ...
private:
virtual uint64_t as_uint64() const { return this->data; }
private:
uint16_t data;
};
then Parent could simply define all comparators, and all Parent types would be comparable.

Use a virtual comparator for single dispatch and dynamic_cast for type casting:
class ABC_base {
public:
virtual ~ABC_base() {}
bool operator < (ABC_base const & rhs) const {
return this->comparator(rhs) < 0;
}
protected:
virtual int comparator (ABC_base const &) = 0;
};
class ABC : public ABC_base {
protected:
virtual int comparator(ABC_base const & rhs) const {
try {
return my_comparator(dynamic_cast<ABC const&>(rhs));
// Run-time cast failed - use double dispatch as fallback
} catch (std::bad_cast&) {
return -rhs.comparator(*this);
}
}
private:
int my_comparator(ABC const & rhs) const {
if (data < rhs.data)
return -1;
if (data == rhs.data)
return 0;
if (data > rhs.data)
return 1;
}
T data;
};
Here's how the code works:
The base class's operator < is called, which uses dynamic lookup to find the comparator. It checks the returned value to see if it's lesser.
The derived class's comparator attempts to downcast the base class reference so that comparison can be done on the derived class's members.
Why the base class reference, instead of using the derived class reference?
Virtual dispatch would not work otherwise due to incorrect function signature.
Should the downcast succeed, it calls the non-virtual private comparator. Otherwise, it uses virtual dispatch again to do (rhs ? *this) and negates the result to compensate for the inverted ordering.
Why not have the cast and comparison in the one virtual function? It will make the code messier since the function will do two things: casting and comparing. Hence, there's a private comparator function. Should you want to use the base function in a derived class, along the lines of class ABC_der : public ABC, call ABC::comparator(static_cast<ABC const&>(rhs)). The use of Base:: forces static dispatch so you don't have to expose the helper comparison function.
Right now, this and rhs are of the same type, so we can finally do the actual comparison. A chain of if statements is used to return a value conformant to Java's Comparable and C's qsort() semantics.

Related

-Woverloaded-virtual warning for const function

I have this piece of code:
class ISerializable
{
public:
virtual bool operator==(const ISerializable* /*value*/) const { return false;};
virtual bool operator!=(const ISerializable* /*value*/) const { return true;};
};
class Point2I : public ISerializable
{
public:
bool operator==(const Point2I& value)
{
return (x == value.x && y == value.y);
}
bool operator!=(const Point2I& value)
{
return !(*this == value);
}
public:
int x;
int y;
};
class Coordinate : public ISerializable
{
public:
virtual bool operator==(const Coordinate& value) const;
virtual bool operator!=(const Coordinate& value) const;
};
It is causing me -Woverloaded-virtual warning on gcc compiler.
I understand this warning due to that function declaration in Point2I hides virtual functions from ISerializable.
But I am not sure if just missing const in Point2I can cause this warning.
Can you please help me understand if it is const which is causing this warning or something else? Warning description from gcc didn't mention anything specifically.
Update:
I found another class Coordinate in my code base which was already overriding this and gcc not throwing warning for this. Only difference in Point2I and Coordinate is I didn't declare it virtual with const in Point2I. It appears just const is hiding base class declaration.
if it is const which is causing this warning or something else?
I'd say that it's something else, namely that you are not actually overriding the base class methods, even if you add const.
The argument const ISerializable* is not the same as const Point2I&.
One solution could be to override the base class methods, using const ISerializable& as the argument, and cast in the overridden methods:
class ISerializable {
public:
// add virtual destructor if you need to delete objects through
// base class pointers later:
virtual ~ISerializable() = default;
virtual bool operator==(const ISerializable&) const { return false; }
virtual bool operator!=(const ISerializable&) const { return true; }
};
class Point2I : public ISerializable {
public:
bool operator==(const ISerializable& value) const override {
auto rhs = dynamic_cast<const Point2I*>(&value);
// rhs will be nullptr if the cast above fails
return rhs && (x == rhs->x && y == rhs->y);
}
bool operator!=(const ISerializable& value) const override {
return !(*this == value);
}
private:
int x = 0;
int y = 0;
};
Example usage:
#include <iostream>
class Foo : public ISerializable { // another ISerializable
public:
};
int main() {
Point2I a, b;
std::cout << (a == b) << '\n'; // true - using Point2I::operator==
Foo f;
std::cout << (a == f) << '\n'; // false - using Point2I::operator==
std::cout << (f == a) << '\n'; // false - using ISerializable::operator==
// this makes the default implementation in ISerializable utterly confusing:
std::cout << (f == f) << '\n'; // false - using ISerializable::operator==
}
Another possible solution could be using CRTP but this would not work if you want to compare different types derived from ISerializable<T>:
template<class T>
class ISerializable {
public:
virtual ~ISerializable() = default;
virtual bool operator==(const T&) const = 0;
virtual bool operator!=(const T&) const = 0;
};
class Point2I : public ISerializable<Point2I> {
public:
bool operator==(const Point2I& value) const override {
return (x == value.x && y == value.y);
}
bool operator!=(const Point2I& value) const override {
return !(*this == value);
}
public:
int x;
int y;
};
There are two problems.
The first one is different types of parameters
In these functions the parameters have the pointer type const ISerializable*
virtual bool operator==(const ISerializable* /*value*/) const { return false;};
virtual bool operator!=(const ISerializable* /*value*/) const { return true;};
and in these functions the parameters have the referenced type const Point2I&
bool operator==(const Point2I& value)
{
return (x == value.x && y == value.y);
}
bool operator!=(const Point2I& value)
{
return !(*this == value);
}
The second one is that the first functions are constant member functions while the second functions are not constant member functions.

How to overload polymorphic == and != operator in c++

class Media {
public:
bool operator==(const Media& other) const {}
bool operator!=(const Media& other) const {}
};
class Book : public Media {
public:
bool operator==(const Book& other) const {} // commenting out this line solves this issue.
bool operator!=(const Book& other) const {}
};
class Game : public Media {
public:
bool operator==(const Game& other) const {}
bool operator!=(const Game& other) const {}
};
int main() {
Book book;
Game game;
bool res = book == game; // doesn't compile.
}
I have these 3 classes and they must have their own == and != operators defined. But then I also have to compare between two siblings using those operators.
I could've written a (pure) virtual function, say, virtual bool equals(const Media& other) const in the base class that subclasses override. And then call that function in the bodies of == and != opertor definition in base class Media. But that feature is gone when I add another bool operator==(const Book& other) const {} in the Book class (the same goes for the Game class too).
Now I want to compare between siblings using those operators and still have all 6 definition in those 3 classes. How do I make it work?
You mentioned in the comments that this form of comparison is an imposed restriction (to compare among siblings of a child type). If its an imposed restriction that you need to somehow perform this with inheritance, then one option is to fulfill the base signature and use dynamic_cast. Note that this is not a clean approach, but it might be the expected solution for this problem if this is some form of assignment.
dynamic_cast uses Runtime Type Information (RTTI) to determine whether an instance to a base class is actually an instance of the derived class. When you use it with a pointer argument, it returns nullptr on failure -- which is easily testable:
auto p = dynamic_cast<const Book*>(&other);
if (p == nullptr) { // other is not a book
return false;
}
// compare books
You can use this along with a virtual function to satisfy the hierarchy. However, to avoid possible ambiguities with c++20's generated symmetric operator==/operator!= functions, it's usually better to do this through a named virtual function rather than the operator== itself in order to prevent ambiguity:
class Media {
public:
virtual ~Media() = default;
bool operator==(const Media& other) const { return do_equals(other); }
private:
virtual bool do_equals(const Media& other) const = 0;
};
class Book : public Media {
...
private:
bool do_equals(const Media& other) const override {
auto* p = dynamic_cast<const Book*>(&other);
if (p == nullptr) { return false; }
return (... some comparison logic ...);
}
...
};
... Same with Game ...
Since we never define operator==(const Book&) or operator==(const Game&), we won't see this shadow the base-class' operator==; instead it always dispatches through the base's operator==(const Media&) -- which is non-virtual and prevents ambiguity.
This would allow a Book and a Game to be comparable, but to return false -- whereas two Book or two Game objects may be compared with the appropriate logic.
Live Example
That said...
This approach is not a good design, as far as software architecture goes. It requires the derived class to query what the type is -- and usually by the time you need to do this, that's an indication that the logic is funky. And when it comes to equality operators, it also leads to complications with symmetry -- where a different derived class may choose to compare things weirdly with different types (imagine a Media that may compare true with other different media; at which point, the order matters for the function call).
A better approach in general is to define each of the respective equality operators between any types that logically require equality comparison. If you are in C++20 this is simple with symmetric equality generation; but pre-C++20 is a bit of a pain.
If a Book is meant to be comparable to a Game, then define operator==(const Game&) or operator==(const Book&, const Game&). Yes, this may mean you have a large number of operator==s to define for each of them; but its much more coherent, and can get better symmetry (especially with C++20's symmetric equality):
bool operator==(const Game&, const Book&);
bool operator==(const Book&, const Game&); // Generated in C++20
bool operator==(const Game&, const Game&);
bool operator==(const Book&, const Book&);
In an organization like this, Media may not even be logical as a 'Base class'. It may be more reasonable to consider some form of static polymorphism instead, such as using std::variant -- which is touched on in #Jarod42's answer. This would allow the types to be homogeneously stored and compared, but without requiring casting from the base to the derived type:
// no inheritance:
class Book { ... };
class Game { ... };
struct EqualityVisitor {
// Compare media of the same type
template <typename T>
bool operator()(const T& lhs, const T& rhs) const { return lhs == rhs; }
// Don't compare different media
template <typename T, typename U>
bool operator()(const T&, const U&) const { return false; }
};
class Media
{
public:
...
bool operator==(const Media& other) const {
return std::visit(EqualityVisitor{}, m_media, other.m_media);
}
private:
std::variant<Book, Game> m_media;
};
Live Example
This would be my recommended approach, provided the forms of media are meant to be fixed and not extended.
You might do double dispatch thanks to std::visit/std::variant (C++17):
class Media;
class Book;
class Game;
using MediaPtrVariant = std::variant<const Media*, const Book*, const Game*>;
class Media {
public:
virtual ~Media () = default;
virtual MediaPtrVariant asVariant() const { return this; }
};
class Book : public Media {
public:
MediaPtrVariant asVariant() const override { return this; }
};
class Game : public Media {
public:
MediaPtrVariant asVariant() const override { return this; }
};
struct EqualVisitor
{
template <typename T>
bool operator()(const T*, const T*) const { return true; }
template <typename T, typename U>
bool operator()(const T*, const U*) const { return false; }
};
bool operator ==(const Media& lhs, const Media& rhs)
{
return std::visit(EqualVisitor(), lhs.AsVariant(), rhs.AsVariant());
}
bool operator !=(const Media& lhs, const Media& rhs)
{
return !(lhs == rhs);
}
int main()
{
Book book;
Game game;
bool res = book == game;
}
Demo

Templated operator ==

I have what is essentially class containing a std::map where the values are shared_ptrs wrapping a container which holds different types. Skeleton code follows:
// Just a basic example class
class MyClass {
public:
explicit MyClass(int i) : mI(i) {}
bool operator==(const MyClass& rhs) { return mI == rhs.mI; }
private:
int mI;
};
// A class into which key value pairs can be added where the value
// can be of a different type.
class MultipleTypeMap {
public:
template <typename T>
void AddObject(const std::string& key, const T object) {
auto ptr = make_shared<B<MyClass>>(std::move(object));
mSharedPtrMap.insert(pair<string, shared_ptr<A>>("key", ptr));
}
// ...
private:
class A {
public:
virtual ~A() = default;
};
template<typename T>
class B : public A {
public:
explicit B(const T& t) : item(t) {}
const T item;
};
map<string, shared_ptr<A>> mSharedPtrMap;
};
int main() {
MyClass m(1);
MultipleTypeMap multiMap;
multiMap.AddObject("test", m);
MyClass n(1);
MultipleTypeMap multiMap2;
multiMap2.AddObject("test", n);
if (multiMap == multiMap2) {
cout << "Equal" << endl;
}
return 0;
}
How should a generic == operator of MultipleTypeMap be written so that it compares the contents of mSharedPtrMap by checking that both the lhs and rhs objects have the same number of keys, the same keys and the same objects where same means that the == operator of the keys / objects evaluates to true?
If you type erase (and later on don't know which type you previously stored), then all the functionality must be provided by the base class interface. So, we need a virtual operator== in A that is implemented in each B.
Here is an implementation:
class MultipleTypeMap {
public:
template <typename T>
void AddObject(const std::string& key, T object) {
auto ptr = std::make_unique<B<T>>(std::move(object));
mMap.emplace(key, std::move(ptr));
}
// ...
bool operator==(const MultipleTypeMap& other) const
{
// Sizes must be equal.
if (mMap.size() != other.mMap.size())
return false;
// Sizes are equal, check keys and values in order.
auto itOther = other.mMap.begin();
for (auto it = mMap.begin(); it != mMap.end(); ++it, ++itOther)
{
if (it->first != itOther->first)
return false;
if (*it->second != *itOther->second)
return false;
}
// No differences found.
return true;
}
bool operator!=(const MultipleTypeMap& rhs) const { return !(*this == rhs); }
private:
class A {
public:
virtual ~A() = default;
virtual bool operator==(const A& other) const = 0;
bool operator!=(const A& other) const { return !(*this == other); }
};
template<typename T>
class B : public A
{
public:
explicit B(const T& t) : item(t) {}
bool operator==(const A& other) const override
{
const B<T>* otherB = dynamic_cast<const B<T>*>(&other);
// If the cast fails, types are different.
if (!otherB)
return false;
// Note: The above is probably slow, consider storing (on construction)
// and checking typeids instead.
// Check item equality.
return item == otherB->item;
}
const T item;
};
std::map<std::string, std::unique_ptr<A>> mMap;
};
Demo with tests
Note: I didn't fix every inconsistency in the original code. (Do you want to move or copy-construct your T? Why store const objects when your MyClass comparison operator is not const?)

Overriding template function in specialized daughter class

I have a templated class MatchBase with a function for the operator == as such
template<typename Element>
class MatchBase{
virtual bool operator ==(const MatchBase<Element>& m) const{
if(_v1 == m.getFirst() && _v2 == m.getSecond()){
return true;
}
return false;
}
I know have a daughter class Match that is template specialized. The class Place used for the specialization does not have an operator== to do the comparison. Thus I'm trying to override the operator== to work with the class Place.
On the things I have tried :
class Match : public betterGraph::MatchBase<graphmatch::Place>{
public :
Match(const graphmatch::Place& v, const graphmatch::Place& vv) :
betterGraph::MatchBase<graphmatch::Place>(v, vv)
{};
virtual bool operator ==(const Match& m) const{
if(_v1.mass_center == m.getFirst().mass_center && _v2.mass_center == m.getSecond().mass_center){
return true;
}
return false;
}
};
I also tried
virtual bool operator ==(const betterGraph::MatchBase<graphmatch::Place>& m) const{
if(_v1.mass_center == m.getFirst().mass_center && _v2.mass_center == m.getSecond().mass_center){
return true;
}
return false;
}
But I always hit an error of the type :
error: no match for ‘operator==’ (operand types are ‘const AASS::graphmatch::Place’ and ‘const AASS::graphmatch::Place’)
if(_v1 == m.getFirst() && _v2 == m.getSecond()){
Because it tries to compile the method from the Base class.
Is there any way for me to override this function of the base class in the daughter class ? I've read the question here but here it's the method that is specialized while my class is specialized so I don't see how to do a forward declaration :/.
The function may be virtual but it's still initialized when you inherit your base class.
This is essential as you might write something like this:
MatchBase<Place> test = Match(p1,p2);
MatchBase<Place> is the base class of Match yet they are not the same.
Calling MatchBase<Place>::operator==() will still call the function defined in your template base class.
You have now multiple option:
- make the function in the base class a pure virtual
- implement Place::operator==()
- pass a comperator as argument to your base class as argument
The first two should be clear (if not please ask). For the third this might be a one possible way to do it:
template<typename Element, typename Less = std::less<Element>>
class MatchBase {
protected:
Element _v1;
Element _v2;
public:
MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
{}
virtual bool operator ==(const MatchBase<Element, Less>& m) const {
Less less;
bool v1Equal = !less(_v1, m.getFirst()) && !less(m.getFirst(), _v1);
bool v2Equal = !less(_v2, m.getSecond()) && !less(m.getSecond(), _v2);
return v1Equal && v2Equal;
}
const Element& getFirst() const { return _v1; }
const Element& getSecond() const { return _v2; }
};
struct Place
{
int mass_center;
};
struct PlaceLess
{
bool operator()(const Place& p1, const Place& p2)
{
return p1.mass_center < p2.mass_center;
};
};
class Match : public MatchBase <Place, PlaceLess>
{
public:
Match(const Place& v, const Place& vv) :
MatchBase<Place, PlaceLess>(v, vv)
{};
};
Another way might be to specialize std::less<T> in this context. So you won't need to pass it as template parameter.
template<typename Element>
class MatchBase {
protected:
Element _v1;
Element _v2;
public:
MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
{}
virtual bool operator ==(const MatchBase<Element>& m) const {
std::less<Element> less;
bool v1Equal = !less(_v1, m.getFirst()) && !less(m.getFirst(), _v1);
bool v2Equal = !less(_v2, m.getSecond()) && !less(m.getSecond(), _v2);
return v1Equal && v2Equal;
}
const Element& getFirst() const { return _v1; }
const Element& getSecond() const { return _v2; }
};
struct Place
{
int mass_center;
};
template<>
struct std::less<Place>
{
bool operator()(const Place& p1, const Place& p2)
{
return p1.mass_center < p2.mass_center;
};
};
class Match : public MatchBase <Place>
{
public:
Match(const Place& v, const Place& vv) :
MatchBase<Place>(v, vv)
{};
};
Of course you could merge these ways so you might override the Less template parameter if needed.
If you don't plan on using predefined types (thinking of int, std::string, etc...) you could also make sure that the class passed as Element must inherit a class/struct that enforces that operator== is implemented:
template <typename T>
struct IComparable
{
virtual bool operator==(const T& other) const = 0;
};
template<typename Element>
class MatchBase {
static_assert(std::is_base_of<IComparable<Element>, Element>::value, "Element must implement comparable");
protected:
Element _v1;
Element _v2;
public:
MatchBase(const Element& v, const Element& vv) : _v1(v), _v2(vv)
{}
virtual bool operator ==(const MatchBase<Element>& m) const {
return _v1 == m._v1 && _v2 == m._v2;
}
};
struct Place : public IComparable<Place>
{
int mass_center;
bool operator==(const Place& other) const
{
return mass_center == other.mass_center;
};
};
class Match : public MatchBase <Place>
{
public:
Match(const Place& v, const Place& vv) :
MatchBase<Place>(v, vv)
{};
};

Where should != operator be defined in a class hierarchy?

Here is a very simple class hierarchy:
class A
{
public:
A( int _a ) : a( _a ) {}
virtual bool operator==( const A& right ) const
{
return a == right.a;
}
virtual bool operator!=( const A& right ) const
{
return !( *this == right );
}
int a;
};
class B : public A
{
public:
B( int _a, int _b ) : A( _a ), b( _b ) {}
virtual bool operator==( const B& right ) const
{
return A::operator==( right ) && b == right.b;
}
int b;
};
As you can see, operator != is defined in the base class. Because I'm very lazy, I don't want to duplicate such a simple code in all the derived classes.
Unfortunatley, with this code:
A a4(4), a5(5), a4bis(4);
assert( a4 == a4bis );
assert( a4 != a5 );
B b1(4,5), b2(4,6);
assert( !(b1 == b2) );
assert( b1 != b2 ); // fails because B::operator== is not called!
b1 != b2 returns false, because it executes A::operator!= which calls then A::operator== rather than B::operator== (even if the operator is virtual, as derived class version parameter is different, they are not linked in the vtable).
So what's the best way to adress != operator in a generic way for a class hierarchy?
One solution is to repeat it in each class, B would then have:
virtual bool operator!=( const B& right ) const
{
return !( *this == right );
}
But that's a pain when you have many classes....I have 30....
Another solution would be to have a generic template approach:
template <class T>
bool operator!=( const T& left, const T& right )
{
return !( left == right );
}
But this bypasses any != operator defined by any class....so it may be risky if one declared it differently (or if one declared a == itself calling !=, it would end up with an infinite loop...). So I feel this solution being very unsafe....except if we can limit the template to be used for all classes derived from the top-level class of our hierarchy (A in my example)....but I don't think this is doable at all.
Note: I'm not using C++11 yet...sorry about that.
Your function in B...
virtual bool operator==( const B& right ) const
...does not override the function in A...
virtual bool operator==( const A& right ) const
...because the argument types differ. (Differences are only allowed for covariant return types.)
If you correct this, you'll then be able to choose how to compare B objects to other A and A-derived objects, e.g. perhaps:
bool operator==( const A& right ) const override
{
if (A::operator==( right ))
if (typeid(*this) == typeid(right))
return b == static_cast<const B&>(right).b;
return false;
}
Note that using the typeid comparison above means only B objects will compare equal: any B will compare unequal to any B-derived object. This may or may not be what you want.
With an implementation for B::operator==, the existing != implementation will properly wrap operator==. As Jarod42 observes, your A::operator== isn't robust in that when the left-hand-side value is an A only the A slice of the right-hand-side object will be compared... you might prefer:
virtual bool operator==(const A& right) const
{
return a == right.a && typeid(*this) == typeid(right);
}
This has the same issues as the B::operator== above: e.g. an A would compare un-equal to a derived object that didn't introduce further data members.
How about something like this ?
class A {
protected :
virtual bool equals(const A& right) const {
return (a == right.a);
}
public :
A(int _a) : a(_a) { }
bool operator==(const A& right) const {
return this->equals(right);
}
bool operator!=(const A& right) const {
return !(this->equals(right));
}
int a;
};
class B : public A {
protected :
virtual bool equals(const A& right) const {
if (const B* bp = dynamic_cast<const B*>(&right)) {
return A::equals(right) && (b == bp->b);
}
return false;
}
public :
B(int _a, int _b) : A(_a), b(_b) { }
int b;
};
Move the comparison logic to a separate (virtual) function equals, and call that function from the operator== and operator!= defined in the base class.
The operators don't need to be re-defined in the derived classes. To change the comparison in a derived class, simply override equals.
Note that the dynamic_cast in the code above is used to ensure that the runtime type is a valid type for performing the comparison. Ie. for B::equals, it's used to ensure that right is a B - this is necessary because otherwise right would not have a b member.