【问题标题】:virtual operator overloading c++虚拟运算符重载 C++
【发布时间】:2021-11-12 08:22:09
【问题描述】:

假设我想为派生类重载“==”运算符,是否需要在派生类头文件中重写重载,或者有没有办法在.cpp文件中实现运算符重载而不必在头文件中添加任何内容?如果是这样,派生运算符的实现在 .cpp 中会是什么样子?

我的标题是什么样的:

class A
{
    public:
    A();
    ~A();
    virtual bool operator==(const A &ref) = 0;
    protected:
    int year;
    string note;
}
class B:A
{
    public:
    B();
    ~B();
    bool operator==(const B &ref); //is this needed or not?
    private:

    int month, day;
}

【问题讨论】:

    标签: c++ oop inheritance operator-overloading


    【解决方案1】:

    C++ 方法覆盖中的函数签名必须完全匹配(如果返回类型是指针,则返回类型除外):

             class A { ... };
             class B : A { ... };
    class A: virtual bool operator==(const A &ref) = 0;
    class B:         bool operator==(const A &ref) override; // OK
    class B:         bool operator==(const B &ref) override; // Invalid
    

    如果从 A 派生的 B 类没有覆盖在 A 中声明为 virtual T foo() = 0 的方法,则 B 类是一个抽象类。

    另请参阅以下术语:

    • 协方差(计算机科学)
    • 逆变(计算机科学)

    【讨论】:

    • 我得到了抽象类出现的问题;但是然后如何声明抽象基类,它的运算符需要被覆盖/实现并因此相应地重载,例如用于在同一类的 rhs 'other' 上操作(这里是派生类 B)? [没有为在基类 [B::operator==(const A& ref)] 上强制实现的运算符创建多余的符号,这些符号很可能永远不会被使用]?
    • @mzoll 我认为与您所询问的内容有关的问题有很多。首先,C++ 本身不支持多分派,因此需要对其进行模拟 (en.wikipedia.org/wiki/Multiple_dispatch#C++)。其次,即使超类中存在虚拟运算符==,也可以定义和调用非虚拟运算符==(请参阅pastebin.com/spJnse1M)。第三,C++ 编译器永远不会全面了解类层次结构——任何未标记为“final”的类都必须隐含地假定可能具有编译器不知道的任意数量的附加子类。
    【解决方案2】:

    如前面的答案所述,您必须在派生类中定义函数。此外,在覆盖时,应始终使用关键字:override

    在你的例子中,

    virtual bool operator==(const A &ref) = 0;
    

    未被覆盖

    bool operator==(const B &ref);
    

    即使你定义了后者,类 B 仍然是抽象的。如果 B 中的operator== 声明为

    bool operator==(const B &ref) override;
    

    然后编译器会产生一个错误,通知我们这个函数没有覆盖任何东西。

    【讨论】:

      【解决方案3】:

      函数必须在派生类中重新声明。否则 1) 派生类也将是抽象的,2) 如果一个类的成员函数最初没有在这个类中声明,则不能定义它。

      考虑到函数声明应该是这样的

      virtual bool operator==(const A &ref) const = 0;
                                            ^^^^^ 
      

      【讨论】:

      • 感谢您提醒我将缺少的 const 添加到声明中。
      • @Karim O. 没问题。:)
      【解决方案4】:

      如果要在子类中重写虚函数,则需要在子类中声明函数重写。

      所以是的,需要声明。


      这样想:类声明可以在很多地方和很多源文件中使用,否则编译器怎么知道函数被覆盖了?

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-08
        • 2019-10-21
        • 2020-09-20
        • 1970-01-01
        • 2015-08-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多