运算符重载摘要 class

operator overloading abstract class

有一个 Student 摘要 class,还有两个派生的 class Grad 和 Undergrad;我想以多种方式重载运算符。

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;
}

Student *students[300] 中查找学生对象 这个操作 == 重载有效并且没有问题, 但我想使用下面的不同方式实现重载。 我该如何实现这个功能??

bool operator==(const Student& x, const Student& y)
{
    // do comparison...
}

虽然这看起来可行,但 type_info::name()

  • 依赖于实现,
  • 不保证在不同类型之间是唯一的,
  • 不保证同一程序的不同执行之间是相同的。

虽然直接比较 type_infos 是可靠的,因此您可以做 if (typeid(*this) == typeid(Grad_Student)) 之类的事情,它会按预期工作。

然而,多态性已经存在,所以你不需要自己实现它,你可以通过分派到虚函数而不是枚举子类来避免很多麻烦(和开销)。
像这样:

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;        
    }
};

请注意 static_cast 是安全的,因为 Student 已经建立了类型相等性。