Definition of the base class `operator ==` in terms of the derived class `operator ==` in C ++ 11?

Suppose I have a type hierarchy:

struct B { ... }; struct D1 : B { ... }; struct D2 : B { ... }; ... struct Dn : B { ... }; 

Each Di has its own operator== defined:

 struct Di : B { bool operator==(const Di&) const { ... } ... }; 

Now I want to define B operator== so that:

 struct B { bool operator==(const B& that) const { // psuedo-code let i, such the dynamic type of this is Di let j, such the dynamic type of that is Dj if (i != j) return false; else return Di::operator==(this, that); } } 

What is the best way to organize this or write it?

(The ultimate goal is that I want to use standard container types with a value of type B * (for example, std::set<B*> ), but to do this use custom Di::operator==s if they belong to the same the same derived class)

+8
c ++ c ++ 11
source share
2 answers

Define a protected virtual function in the base class. Make it pure virtual to ensure that every subclass of Di provides an implementation. The function will know the purpose of the cast because it belongs to Di Call this function from the == operator in the base class and perform a comparison, for example:

 struct B { bool operator==(const B& that) const { return this->equals(that); } protected: virtual bool equals(const B& other) const=0; }; struct D1 { protected: virtual bool equals(const B& other) const { D1 *that = dynamic_cast<D1*>(&other); if (!that) return false; // Perform D1-specific comparison here. // You can use the == operator of D1, but you do not have to: return (*this) == (*that); } }; 

The effect of this construction makes the implementation of the == operator virtual.

+6
source share

Below is a small dasblinkenlight solution with added features (for example, less code duplication)

 #include <typeinfo> // for typeid struct B { bool operator==(const B& that) const { if (this == &that) // trivially equal return true; if (typeid(*this) != typeid(that)) // trivially different return false; return equals(that); // delegates to the virtual function } // polymorphic classes must have virtual destructors virtual ~B() = default; protected: virtual bool equals(const B& that) const = 0; }; struct D1 : B { bool operator ==(const D1& that) const { // ... } private: // private because this function is not meant to be called except through // B::equals bool equals(const B& that) const override { // static_cast is safe here because execution only gets here if the // dynamic type of that is D1 (this was tested in B::operator =() return *this == static_cast<const D1&>(that); } }; 
+1
source share

All Articles