Вызов метода дочернего класса при обработке списка объектов родительского класса - PullRequest
1 голос
/ 04 декабря 2009

Похоже, что этот вопрос может быть несколько распространенным, но я ничего не нашел при просмотре StackOverflow или межплетений.

Я обнаружил метод в классе C ++, который принимает список (например) Parent объектов. Для этого примера предположим, что есть два класса, производные от Parent: Child1 и Child2.

Для каждого объекта в списке метод проверяет, имеет ли объект тип Child2 (с помощью метода IsOfType(), который реализует каждый класс), и, если это так, он вызывает метод, который предоставляется только Child2 класс.

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

Одним из вариантов может быть объявление метода Child2 в классе Parent, чтобы все объекты Parent реализовали его. Однако в этом случае только класс Child2 будет реализовывать любое поведение при переопределении метода.

Ваши мысли? Заранее спасибо!

Ответы [ 4 ]

3 голосов
/ 04 декабря 2009

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

class Parent {
public:
   virtual int doSomething() {}
};

class Child1 : public Parent {
};

class Child2 : public Parent {
public:
    virtual int doSomething();

Теперь вы просто пропускаете вызов IsOfType и вызываете doSomething для всех переданных вам указателей.

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

2 голосов
/ 04 декабря 2009

Вы можете объявить новый метод в интерфейсе, который реализует только Child2. Затем вы можете использовать dynamic_cast<ISomeOtherInterface>, чтобы увидеть, поддерживает ли объект расширенную функцию. Это приведение приведет к указателю null для объектов, которые не поддерживают дополнительный интерфейс.

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

1 голос
/ 04 декабря 2009

Если ваш тест IsOfType () пройден, вы можете привести (указатель на) родительский объект к объекту Child2 и получить доступ к его конкретным функциям-членам.

EDIT: Это зависит от вашего дизайна и от того, насколько строго вы гарантируете, что реализация IsOfType () даст правильные ответы (т. Е. Она также работает, когда вы добавляете новые подклассы через неделю). Возможно, безопаснее использовать встроенный Typeid . Реализация каждого возможного метода, который любой дочерний элемент когда-либо имел бы в родительском элементе, будет затруднена, поэтому апскейтинг вполне допустим, когда метод действительно семантически специфичен для класса Child2.

0 голосов
/ 04 декабря 2009

Вы можете найти Шаблон посетителя , полезный в этом случае. Это позволит самим объектам (child1, child2 и т. Д.) Перезвонить вам со своим статическим типом и предпринять соответствующие действия.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...