首页 > 解决方案 > 运算符继承

问题描述

我有以下代码:

class Rectangle
{
protected:
    int a, b;
public:
    Rectangle(int a, int b) : a(a), b(b) {}
    int area() { return a*b; }
    Rectangle operator+(const Rectangle & other)
    {
        Rectangle temp(0, 0);
        temp.a = a + other.a;
        temp.b = b + other.b;
        return temp;
    }
    void operator=(const Rectangle & other)
    {
        a = other.a;
        b = other.b;
    }
};

class Square : public Rectangle
{
public:
    Square(int a) : Rectangle(a, a) {}
};

int main()
{
    Square s1(3);
    Square s2(1);
    cout << (s1 + s2).area();
    s1 = s1 + s2;
}

没问题,cout << (s1 + s2).area();但在s1 = s1 + s2;编译器给我一个错误:

'operator=' 不匹配(操作数类型为 'Square' 和 'Rectangle')

为什么这条线不起作用?

标签: c++

解决方案


如果您不提供赋值运算符,编译器将为您声明一个。在这里,编译器生成Square::operator=(const Square&). 赋值运算符 fromRectangle被此运算符隐藏。您可以通过声明Rectangle::operator=将其纳入范围:using

class Square : public Rectangle
{
public:
    using Rectangle::operator=;

    // ...
};

现在代码可以编译,但它有缺陷。正如 Konrad Rudolph、Jarod42 和 molbdnilo 的评论中所指出的,派生SquareRectangle逻辑上是错误的,因为它违反Liskov 的替换原则。您现在可以将 a 分配Rectangle给 a Square,这样的分配没有意义。


推荐阅读