There is an Student abstract class, and two derived class Grad and Undergrad; and I want to overload operator in several ways.
student.h
class Student {
protected:
string Name;
int Stu_num;
public:
virtual void print() = 0;
bool operator==(const Student& x) const;
// constructor...
}
class Grad_Student : public Student {
private:
string Lab;
public:
void print();
bool operator==(const Grad_Student& x) const;
// constructor...
}
class Undergrad_Student : public Student {
private:
string Major;
public:
void print();
bool operator==(const Undergrad_Student& x) const;
// constructor...
}
student.cpp
bool Student::operator==(const Student& x) const {
if (this->Name == x.Name && this->Stu_num == x.Stu_num) {
if (typeid(*this).name() != typeid(x).name()) {
return false;
}
else if (!(strcmp(typeid(*this).name(), "12Grad_Student"))) {
return *dynamic_cast<const Grad_Student *>(this) == *dynamic_cast<const Grad_Student *>(&x);
}
else {
return *dynamic_cast<const Undergrad_Student *>(this) == *dynamic_cast<const Undergrad_Student *>(&x);
}
}
else {
return false;
}
}
bool Grad_Student::operator==(const Grad_Student& x) const {
return this->Lab == x.Lab;
}
bool Undergrad_Student::operator==(const Undergrad_Student& x) const {
return this->Major== x.Major;
}
To find student object in Student *students[300]
this operation == overloading works and doen't have problem,
but I want to implement overloading in different way using below.
How can I implement this function??
bool operator==(const Student& x, const Student& y)
{
// do comparison...
}
CodePudding user response:
While that may appear to work, type_info::name()
is
- implementation-dependent,
- not guaranteed to be unique between different types,
- not guaranteed to be the same between different executions of the same program.
Comparing type_info
s directly is reliable though, so you could do things like if (typeid(*this) == typeid(Grad_Student))
and it would work as expected.
However, polymorphism already exists, so you don't need to implement it yourself, and you can avoid a lot of trouble (and overhead) by dispatching to a virtual function instead of enumerating subclasses.
Something like this:
class Student {
public:
bool equals(const Student& s) const
{
return Name == s.Name
&& Stu_num == s.Stu_num
&& typeid(*this) == typeid(s)
&& equals_internal(s);
}
private:
virtual bool equals_internal(const Student& s) const = 0;
string Name;
int Stu_num;
};
bool operator==(const Student& lhs, const Student& rhs)
{
return lhs.equals(rhs);
}
class Grad_Student : public Student {
private:
string Lab;
bool equals_internal(const Student& s) const override
{
return Lab == static_cast<const Grad_Student&>(s).Lab;
}
};
class Undergrad_Student : public Student {
private:
string Major;
bool equals_internal(const Student& s) const override
{
return Major == static_cast<const Undergrad_Student&>(s).Major;
}
};
Note that the static_cast
s are safe, since Student
has already established the type equality.