What's the Right Way to Overload Operator== for a Class Hierarchy

What's the right way to overload operator== for a class hierarchy?

For this sort of hierarchy I would definitely follow the Scott Meyer's Effective C++ advice and avoid having any concrete base classes. You appear to be doing this in any case.

I would implement operator== as a free functions, probably friends, only for the concrete leaf-node class types.

If the base class has to have data members, then I would provide a (probably protected) non-virtual helper function in the base class (isEqual, say) which the derived classes' operator== could use.

E.g.

bool operator==(const B& lhs, const B& rhs)
{
return lhs.isEqual( rhs ) && lhs.bar == rhs.bar;
}

By avoiding having an operator== that works on abstract base classes and keeping compare functions protected, you don't ever get accidentally fallbacks in client code where only the base part of two differently typed objects are compared.

I'm not sure whether I'd implement a virtual compare function with a dynamic_cast, I would be reluctant to do this but if there was a proven need for it I would probably go with a pure virtual function in the base class (not operator==) which was then overriden in the concrete derived classes as something like this, using the operator== for the derived class.

bool B::pubIsEqual( const A& rhs ) const
{
const B* b = dynamic_cast< const B* >( &rhs );
return b != NULL && *this == *b;
}

What is the right way to overload the assignment operator for a derived class?

Assuming you have an operator= in the Base class, you could write:

Derived& Derived::operator=(const Derived &a){

Base::operator=(static_cast<Base const&>(a));

r = a.r;
g = a.g;
b = a.b;

return *this;
}

How to overload == operator without making it a friend function?

Like @HolyBlackCat pointed out, you can provide the operator== overload as a free function. It will be a free-function, meaning you can either write

#ifndef SOMECLASS_H
#define SOMECLASS_H

// namespaces if any

class SomeClass
{
// Other class declarations, constructors
};

bool operator==(const SomeClass& a, const SomeClass& b) noexcept
{
// definition
}

// end of namespaces if any!

#endif // end of SOMECLASS_H

or

declare operator== in the header and provide the definition of the free function in the corresponding cpp file

Overload Operator for a derived class of a template class

The proper solution is a mix of code in your attempts 1 and 2.

template <
typename Class,
typename = typename std::enable_if< std::is_base_of<Base<Class>, Class>::value >::type
>
std::ostream& operator<<(std::ostream& os, const Class& obj)
{
os << obj.name << "[ ";
os << Base<Class>::f(obj);
os << " ]";

return os;
}
  • You need to take Class& and not Base<Class>&, because you (might)want to operate on the members of Class.
  • However, enable_if is used so that the operator only works for types that are derived from Base; this prevents it creeping into other overloads (in general, overloads and templates mix poorly), as such a template overload could potentially match anything.
  • We also explicitly need to pass the Class to the Base to get the proper f.

Also, a small note; with a modern compiler, you can spell it a bit more nicely:

typename = std::enable_if_t<std::is_base_of_v<Base<Class>, Class>>

What's the right way to overload the stream operators for my class?

Your implementation is fine. The only additional step you need to perform is to declare your operator as a friend in Thing:

class Thing {
public:
friend istream& operator>>(istream&, Thing&);
...
}

overload operator within a class in c++

How do I overload the << operator for my_struct ONLY within the class?

Define it as

static std::ostream & operator<<( std::ostream & o, const my_struct & s ) { //...

or

namespace {
std::ostream & operator<<( std::ostream & o, const my_struct & s ) { //...
}

in the .cpp file in which you implement MyClass.

EDIT: If you really, really need to scope on the class and nothing else, then define it as a private static function in said class. It will only be in scope in that class and it's subclasses. It will hide all other custom operator<<'s defined for unrelated classes, though (again, only inside the class, and it's subclasses), unless they can be found with ADL, or are members of std::ostream already.

How do I overload the assignment operator as to allow my class to equal a primitive type such as 'int'

You've confused assignment with initialization.

Foo f = 1; //initialization
f = 2; //assignment

You need to make a constructor that accepts an int too.

Foo(int i) : value(i) {}

//main

Foo f = 1; //uses constructor

Being that it is a single argument constructor (converting constructor), if you don't wish int to be implicitly convertible to Foo, you should make the constructor explicit.

virtual operator overloading c++

If you want to override a virtual function in a child-class, then you need to declare the function override in the child class.

So yes, the declaration is needed.


Think about it this way: The class declaration could be used in many places and many source files, how else would the compiler know that the function has been overridden?



Related Topics



Leave a reply



Submit