Reputation: 183
class Eq
{
public:
virtual bool operator==(Eq operand) = 0;
};
class Day : public Eq
{
public:
enum DAY
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
} day;
Day(DAY init_day) : day(init_day){}
bool operator==(Day operand)
{
return day == operand.day;
}
};
int main()
{
Day d1(Day::Monday);
Day d2(Day::Monday);
d1 == d2;
return 0;
}
This is the code which I trying to implement. Class Eq works like as interface of JAVA. It has only one member function, operator==. Operator== takes one operand which is same type with the class which is deriving Eq class. For example, class Day derives Eq, so it have to implement operator== which is taking Day type parameter.
And there is the problem. First, both operator== functions have different signatures. So the compiler thinks they are not same functions, but overrided functions. Second, if any function in this code takes Eq class parameter, then compiler makes error because instance of the abstract class is not available.
So this is the question. How can I make operator== function in T class to take T class parameter, where T is implementation of Eq class?
Upvotes: 3
Views: 113
Reputation: 73366
Your approach has two main flaws:
operator==
for Day
does not match the one of Eq
so it won't work. There are already nice template solutions proposed, which is very convenient for this kind of problems. For the sake of completeness, I propose you a templateless alternative.
First chance Eq
:
class Eq
{
public:
virtual bool operator==(Eq& operand) = 0; // References passing doesn't slice
};
Then update its overriding in Day
:
bool operator==(Eq& operand)
{
if (dynamic_cast<Day*>(&operand)) // check if types compatible
return day == dynamic_cast<Day*>(&operand)->day;
else return false; // else the objects are different anyway
}
Finally you can test in main()
:
...
if (d1 == d2) // check that result is as expected !
cout << "Yes it works !";
else cout << "Hhmmm...";
Upvotes: 1
Reputation: 20101
You can do this by sending in references instead.
class Eq
{
public:
virtual bool operator==(Eq& operand) = 0; // Changed to reference
};
class Day : public Eq
{
public:
enum DAY
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
} day;
Day(DAY init_day) : day(init_day){}
bool operator==(Eq& operand) // Changed to reference of Eq.
{
const Day* other = dynamic_cast<Day*> (&operand);
if (other == nullptr) // Checking if the operand is of Day type.
return false; // If not, those two objects cannot be the same.
return day == other->day; // Do the comparison.
// Note the '->' instead of '.' since 'day' is a pointer.
}
};
You are missing a few key points on how C++ works compared to Java (which I guess you are more familiar with).
Here are a couple of good links I found regarding how to do operator== overloading when dealing with inheritance. (They also talk about the public-non-virtual/non-public-virtual discussion.)
Equality Test for Derived Classes in C++
What's the right way to overload operator== for a class hierarchy?
Upvotes: 2
Reputation: 5239
you can use CRTP:
template <typename DerivedType>
class Eq
{
public:
virtual bool operator==(DerivedType operand) = 0;
};
class Day : public Eq<Day>
{
public:
enum DAY
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
} day;
Day(DAY init_day) : day(init_day){}
bool operator==(Day operand)
{
return day == operand.day;
}
};
Upvotes: 2
Reputation: 17595
You could introduce a type parameter T
in Eq
and derive Day
from Eq<Day>
to enforce the desired signature of operator==
.
Upvotes: 3