перегрузка на подклассы - PullRequest
0 голосов
/ 08 августа 2011

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

Animal * pg = new Pigeon();
Animal * pgone = new Pigeon();

Animal * babypigeon = *pgone + *pg;

Где Animal - базовый тип, а Pigeon - производный тип. Я задавался вопросом, стоит ли мне просто перегружать операторы производного типа или мне тоже нужно перегружать операторы базового типа?

Предполагается, что все производные типы будут созданы с использованием базового указателя.

Ответы [ 4 ]

3 голосов
/ 08 августа 2011

Ваша логика отключена, и ваша программа не будет делать то, что вы ожидаете.Вы добавляете туда указатели.Оператор + вызываться не будет.

Вам нужно что-то вроде

babypigeon = (*pgone) + (*pg);

В этом случае вы добавляете двух животных.Таким образом, ваш оператор + должен быть перегружен в классе Animal.

Решением этой проблемы будет вызов некоторых виртуальных методов из оператора + и наличие там логики.

EDIT:

class Animal{
//....
    virtual Animal plusLogic( const Animal& otherAnimal ) const;
    Animal operator + ( const Animal& otherAnimal ) const
    {
        return this->plusLogic(otherAnimal);
    }
}

class Pigeon : public Animal{
//.....
    virtual Animal plusLogic( const Animal& otheAnimal ) const;
}
Animal Pigeon::plusLogic (const Animal& otherAnimal) const
{
    //logic heree
}

Таким образом, вызов оператора + для Animal типа Pigeon вызовет функцию plusLogic в классе Pigeon (поскольку он является виртуальным).

2 голосов
/ 08 августа 2011

Вы не можете сделать это - pgone и pg являются типами указателей и не могут иметь перегруженные операторы для них.Вам нужно будет иметь

Animal* baby = *pgone + *pg;

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

1 голос
/ 09 августа 2011

Я вижу несколько очень простых проблем с этим подходом:

  1. Не существует универсально согласованного оператора для спаривания голубей (на самом деле, не лучше ли это выразить с помощью *, а не +?), Так что это явно нарушает первое основное правило перегрузки оператора .
    Хотя @Alexandre пошутил, у него есть хороший комментарий: лучше использовать хорошо названную функцию .

  2. Перегрузка оператора - это то, что хорошо подходит для типов значений и плохо подходит для полиморфных типов . Нет смысла спаривать двух животных.
    Вы не можете в общем случае указать (динамический) тип результата, потому что вам придется создавать новый тип для каждой перестановки, создавая тем самым даже новые возможные перестановки, что приводит к бесконечному распространению типов. (А также, если вы попытаетесь, у вас могут быть лиги защиты животных, и они могут быть довольно раздражающими.)

  3. Оператор, используемый в вашем примере, берет два объекта по ссылке, но должен будет возвращать указатель на динамически размещенный объект. Это не только звучит ужасно неправильно, но и так.
    Для начала: теперь вы не можете больше добавлять цепочки (pg1 + pg2 + pg3, потому что результат сложения не того же типа, что и его операнды. Это очень нелогично и нарушает второе основное правило перегрузки оператора .
    И я даже не буду касаться вопросов, например, кому принадлежит возвращенный объект и кто отвечает за его очистку.

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

1 голос
/ 08 августа 2011
  • вы не можете перегружать операторы для типов указателей, поэтому ваш код не должен компилироваться (Редактировать: вопрос был изменен, и не должен компилировать часть больше не действительна),

  • в общем случае перегрузка оператора лучше всего работает с неполиморфным типом:

    • см. Ограничение выше,
    • с полиморфным типом, вам часто нужномножественный distpatch, чтобы иметь возможность сделать что-то значимое
    • возвращая полиморфное значение, имеет свою собственную проблему (кто является владельцем, если нужно что-то выделять), увеличиваемую тем фактом, что операторы объединяют диски (a+b+c)
    • потенциальное решение - идиома буквы / конверта
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...