Переопределение не void функции в C ++, где возвращается возвращаемое значение? - PullRequest
0 голосов
/ 21 мая 2011

Я пишу программу с тремя уровнями наследования. Требуется перегрузить operator== в базовом классе, а затем переопределить эту функцию в производных классах (мне не разрешено изменять этот дизайн).

Функция - это bool, который выполняет сравнение двух элементов для каждого элемента. Как мне обработать возвращаемое значение supers? В Java получить это значение просто: я просто делаю первую строку переопределенной функции вызовом super, например:

retValue = super.myFunction();

Мне нужно добиться того же результата, но в C ++ и с ужасной перегрузкой операторов. Некоторый псевдокод для перегруженной функции был бы очень признателен.

У меня также есть еще один вопрос, связанный с этим; Что произойдет, если оператор используется в экземплярах из разных подклассов? Например, sub1 и sub2 наследуют от base, какая версия функции будет выполняться для следующей строки кода в Main:

if (sub1 == sub2)

Будет ли генерироваться ошибка компилятора?

Редактировать: Во-первых, я студент, поэтому я не могу написать код для выполнения этой задачи так, как мне бы хотелось. Состояние требований программы;

"Перегрузка оператора транспортного средства: оператор ==

Класс Vehicle должен переопределить оператор ==. Два объекта равны, если все их поля данных равны и если их списки пассажиров идентичны. Это необходимо определить в базовом классе, а затем переопределить в производных классах. "

У меня нет кода для публикации, потому что, читая ответ Билли, я понял, что на самом деле написал функцию operator ==, свободную от класса (что не позволит мне переопределить ее и не встретит требования программы).

Пример;

if (sub1 == sub2)

был полностью гипотетическим. На самом деле у меня будет массив объектов Vehicle, у меня есть класс Car и Airplane, который наследуется от Vehicle, а затем MagicSchoolBus, который наследуется от Car, и Xwing, который наследуется от Airplane. В классе Vehicle у меня есть int 'vType_', который определяет конкретный подкласс, к которому принадлежит каждый экземпляр Vehicle. Чтобы предотвратить сбой во время выполнения, я просто проверю, чтобы убедиться, что объекты имеют одинаковый vType_, прежде чем использовать оператор ==.

Столько, сколько я бы предпочел написать функцию сравнения, мне не позволено. Мне нужно найти способ использовать возвращаемое значение из функции operator == в базовом классе, потому что он сравнивает несколько элементов данных, и, конечно, я буду понижен, если переписываю этот код в каждом из производных классов.

Если я не могу использовать это возвращаемое значение, мне придется либо переписать код, либо я получу неправильный результат, если у объекта разные значения в элементах базового класса, но те же значения в производном классе.

Мне придется переписать эту функцию как члена класса Vehicle, но я все равно опубликую ее в надежде, что она может быть полезной. Каждый из производных классов имеет еще несколько членов, специфичных для этих типов транспортных средств, и массив объектов Passenger, которые будут сравниваться.

// оператор равенства перегружен для сравнения элементов

оператор bool == (Vehicle & obj1, Vehicle & obj2) { bool retValue = false;

if (strcmp(obj1.getName(), obj2.getName()) == 0)
{
    if (obj1.getType() == obj2.getType() && obj1.getFuel() == obj2.getFuel())
    {
        if (obj1.getRate() == obj2.getRate() && obj1.getStatus() == obj2.getStatus())
        {
            retValue = true;
        }
    }
}

return retValue;

}

Ответы [ 3 ]

3 голосов
/ 21 мая 2011

, поскольку C ++, в отличие от Java, поддерживает множественное наследование, вам необходимо явно указать, какой суперкомпьютер вам нужно использовать, на SUPER::operator==() (замените SUPER реальным именем суперкласса ..)

2 голосов
/ 21 мая 2011

Требуется перегрузить оператор == в базовом классе, а затем переопределить эту функцию в производных классах

Это кажется очень странным занятием. Перегрузки операторов обычно должны быть свободными функциями, а не членами класса, где это возможно. Не могли бы вы опубликовать код, описывающий, что вы хотите сделать более конкретно? Потому что общая реализация того, что вы хотели бы, невозможна. Например. если вы сравните Derived 1 и Derived 2 через указатель базового класса, как компилятор узнает, какой operator== вызвать? И Derived 1, и Derived 2 реализуют эту функцию, но выбора не будет. Производные классы должны просто реализовывать == сокрытие реализации базового класса, в тех немногих случаях, когда кому-то может понадобиться сделать что-то подобное.

Не смешивайте перегрузку оператора с виртуальными функциями - это болезненно и не так, как перегрузка оператора предназначена для работы.

Как мне обработать возвращаемое значение supers?

Вы нет. В C ++ нет такого понятия, как «супер» (с одной стороны, если вы наследуете от двух классов, как язык должен знать, что такое базовая версия?: P). Если вы хотите вызвать перегрузку базового класса, вы вызываете функцию базового класса напрямую. Пример:

class SomeBaseName
{
    int aMember;
public:
    bool operator==(const SomeBaseName& rhs)
    {
        return aMember == rhs.aMember;
    };
};

class Derived : public SomeBaseName
{
    int anotherMember;
public:
    bool operator==(const Derived& rhs) //Note that this is not a virtual function, it is *hidden* instead.
    {
        if (!(SomeBaseName::operator==(rhs))
            return false;
        return anotherMember == rhs.anotherMember;
    }
};

Я действительно очень рекомендую вам не делать этого, хотя ... бессмысленно делать такие вещи с перегрузкой операторов.

Что произойдет, если оператор будет использоваться в экземплярах из разных подклассов? Например, sub1 и sub2 наследуют от base, какая версия функции будет выполнена для следующей строки кода в Main

Никто не будет вызван. Вызов неоднозначный и приведет к ошибке во время компиляции.

Наконец, последний совет: не пытайтесь изучать C ++ с точки зрения Java. Изучайте C ++ как новый язык. Это разные языки - более того, чем предполагает их похожий синтаксис. C ++ позволяет вам делать несколько вещей, для которых абсолютно не эквивалентен в Java (например, арифметика указателей, перегрузка операторов, множественное наследование, метапрограммирование шаблонов и т. Д.), И хотя есть некоторые вещи, которые похожи в места, идиоматические примеры на обоих языках сильно отличаются друг от друга. Если вы думаете о вещах как о Java-эквивалентах в местах, вы будете сбиты с толку, когда языки различаются или когда C ++ накапливает концепции в своей (очень разнородной) объектной модели.

1 голос
/ 21 мая 2011

Если вы наследуете от класса, тогда вы должны использовать явный квалификатор.Ключевого слова нет.

class A {
public:
    virtual bool operator==(const A&);
};
class B : public A {
public:
    virtual bool operator==(const B& other) {
        bool result = A::operator==(other);
        //.. do other stuff
    }
};

Если вы не определили новое, то вызывается базовое.

...