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 notBase<Class>&
, because you (might)want to operate on the members ofClass
. - However,
enable_if
is used so that the operator only works for types that are derived fromBase
; 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 theBase
to get the properf
.
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
How to Concatenate Two Strings in C++
Is It Legal to Recurse into Main() in C++
How to Use a Member Variable as a Default Argument in C++
Increasing Accuracy of Solution of Transcendental Equation
Macro For Dllexport/Dllimport Switch
Why Does Call-By-Value Example Not Modify Input Parameter
C/C++ Include Header File Order
Why Do We Not Have a Virtual Constructor in C++
View Array in Visual Studio Debugger
C++: Const Reference, Before VS After Type-Specifier
A Free Tool to Check C/C++ Source Code Against a Set of Coding Standards
Determine the Size of a C++ Array Programmatically
How Is Std::String Implemented
Is Multiplication and Division Using Shift Operators in C Actually Faster