Home > database >  operator overloading abstract class
operator overloading abstract class

Time:09-22

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_infos 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_casts are safe, since Student has already established the type equality.

  • Related