In
bool operator > (const CONSTRAINT &rhs)
rhs
равно const
.Это не может быть изменено внутри этого метода.Но ...
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<
был реализован как Свободная функция .Подробнее об этом и многом другом о перегрузке операторов см. Каковы основные правила и идиомы перегрузки операторов?