【问题标题】:How can I overload an operator for an abstract class?如何为抽象类重载运算符?
【发布时间】:2019-07-11 17:13:43
【问题描述】:

我对 C++ 比较陌生,我的教授在上他的课时并没有像我想的那样详细介绍运算符重载。我正在尝试实现一种方法来比较所有继承抽象类的对象(使用 > 或

我尝试让它成为父类的成员,但我不知道如何从基类内部调用纯虚函数。然后我尝试使用模板,但这让我很头疼(我的教授也没有深入了解这些)。

我知道我在操作符函数中完全失败了(如果有任何有关正确语法的帮助,我们将不胜感激。

#include <iostream>

enum cType { point, maxima, inflection };

class CONSTRAINT {
public:
    //coordinates
    int x, y;
    //gets what type of constraint the object is
    virtual cType getType() = 0; //pure virtual
    //I'm sure this syntax is horrendous and completely wrong.
    //I was just trying to emulate what I found online :(
    bool operator > (const CONSTRAINT &rhs) { 
            //If the constraints have the same type, compare by their x-value
        if (getType() == rhs.getType())
            return (x > rhs.x);
            //Otherwise, it should be point > maxima > inflection
        else
            return (getType() > rhs.getType());
    }
};
class POINT : public CONSTRAINT {
public:
    virtual cType getType() { return point; }
};
class MAXIMA : public CONSTRAINT {
public:
    virtual cType getType() { return maxima; }
};
//I have another inflection class that follows the pattern

int main() {
    POINT point1, point2;
    point1.x = 3;
    point2.x = 5;
    MAXIMA maxima;
    maxima.x = 4;
    std::cout << (point1 > point2);
    std::cout << (point2 > point1);
    std::cout << (maxima > point2);
    std::cout << (point1 > maxima );
    return 0;
}

我希望:0110 如果程序可以编译。

相反,我收到以下错误:

“对象具有与成员函数“CONSTRAINT::getType”不兼容的类型限定符”

“'cType CONSTRAINT::getType(void)': 无法将'this'指针从'const CONSTRAINT'转换为'CONSTRAINT &'”

谢谢。

【问题讨论】:

  • 一般来说,拥有虚拟operator&gt; 或任何其他虚拟二元运算符是一个非常糟糕的主意™。有例外,但它们很少而且相差甚远。引用任何类型的“类型标识符”(例如您的enum cType)来执行业务逻辑是另一种非常糟糕的想法。

标签: c++ operator-overloading abstract-class


【解决方案1】:

bool operator > (const CONSTRAINT &rhs)

rhsconst。它不能在此方法内更改。但是……

virtual cType getType() = 0; //pure virtual

不是const 方法。这意味着该方法可以更改rhs,因此编译器拒绝调用它。

解决方法:声明方法const

virtual cType getType() const = 0; //pure virtual

现在编译器承诺调用该函数将不允许更改rhs。如果getType 的实现试图更改调用它的对象,编译器也会强制执行此操作并拒绝编译程序。

旁注:

一旦方法被声明为virtual,所有覆盖也将是virtual

override 关键字将在方法应覆盖但由于不匹配而未覆盖时捕获错误。将const 添加到基类方法,而不是派生类方法,是一个很好的例子,说明这很有帮助。

由于这段代码看起来利用了运行时多态性,因此您可能希望在基类中使用虚拟析构函数,以确保在您有一天希望通过指向基类的指针delete 派生类时销毁正确的类班级。

总结一下:

#include <iostream>

enum cType { point, maxima, inflection };

class CONSTRAINT {
public:
    //coordinates
    int x, y;

    virtual ~CONSTRAINT() = default;
//  ^ added

    //gets what type of constraint the object is
    virtual cType getType() const = 0; //pure virtual
//                          ^ added
    //I'm sure this syntax is horrendous and completely wrong.
    //I was just trying to emulate what I found online :(
    bool operator > (const CONSTRAINT &rhs) {
            //If the constraints have the same type, compare by their x-value
        if (getType() == rhs.getType())
            return (x > rhs.x);
            //Otherwise, it should be point > maxima > inflection
        else
            return (getType() > rhs.getType());
    }
};
class POINT : public CONSTRAINT {
public:
    cType getType() const     override { return point; }
//                  ^ added   ^ added
};
class MAXIMA : public CONSTRAINT {
public:
    cType getType() const     override { return maxima; }
//                  ^ added   ^ added
};
//I have another inflection class that follows the pattern

int main() {
    POINT point1, point2;
    point1.x = 3;
    point2.x = 5;
    MAXIMA maxima;
    maxima.x = 4;
    std::cout << std::boolalpha // < added. prints true and false instead of 1 and 0
              << (point1 > point2) << '\n'
              << (point2 > point1) << '\n'
              << (maxima > point2) << '\n'
              << (point1 > maxima);
    // took advantage of chaining and added newlines to the output for clarity
    return 0;
}

最后附注:一般建议将operator&lt; 实现为Free Function。有关这方面的更多信息,以及关于运算符重载的许多其他智慧,请参阅What are the basic rules and idioms for operator overloading?

【讨论】:

    猜你喜欢
    • 2021-11-13
    • 2016-07-15
    • 2012-06-16
    • 1970-01-01
    • 2018-02-22
    • 1970-01-01
    • 2021-11-13
    • 2015-05-09
    • 1970-01-01
    相关资源
    最近更新 更多