C ++ Перегрузка функции на основе производного класса shared_ptr - PullRequest
7 голосов
/ 31 мая 2011

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

У меня есть класс Parent и два унаследованных от него класса:

class Son : public Parent { ... };
class Daughter : public Parent { ... };

Затем я объявляю два shared_ptrБазовый класс и создайте для них экземпляр с shared_ptr для каждого из производных классов:

shared_ptr<Parent> son = shared_ptr<Son>(new Son());
shared_ptr<Parent> daughter = shared_ptr<Daughter>(new Daughter());

Наконец, я хотел бы иметь класс, который обрабатывает shared_ptr<Parent> в зависимости от того, на какой из производных классов он указываетк.Могу ли я использовать перегрузку функций для достижения этого эффекта, вопрос:

class Director {
public:
    void process(shared_ptr<Son> son);
    void process(shared_ptr<Daughter> daughter);
    ...
};

Поэтому я хотел бы иметь возможность написать следующий код:

shared_ptr<Parent> son = shared_ptr<Son>(new Son());
shared_ptr<Parent> daughter = shared_ptr<Daughter>(new Daughter());
Director director;
director.process(son);
director.process(daughter);

Прямо сейчас у меняделать (чего я хотел бы избежать):

director.process_son(boost::shared_polymorphic_downcast<Son>(son));
director.process_daughter(boost::shared_polymorphic_downcast<Daughter>(daughter));

Ответы [ 3 ]

7 голосов
/ 31 мая 2011

Невозможно перегрузить таким образом, вам понадобится оператор switch для достижения чего-то похожего с диспетчеризацией внутри одного метода на Director.

Возможно, вам следует переместить метод process() вParent class (и переопределите его в Son и Daughter), чтобы вы могли использовать нормальное разрешение виртуальной функции для вызова правильного.

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

Я не уверен, есть ли какие-нибудь лучшие способы, поэтому я обычно использую шаблон Visitor http://en.wikipedia.org/wiki/Visitor_pattern или аналогичные приемы двойной отправки при такой необходимости.

Ваши объекты, вероятно, не знают, что shared_ptrСами по себе, но обычно простые ссылки работают достаточно хорошо.

0 голосов
/ 31 мая 2011

В идеале Parent должен обеспечить интерфейс, достаточно богатый для Director, чтобы правильно обрабатывать каждого потомка, без необходимости знать, какой это ребенок.

class Director {
public:
    void process(shared_ptr<Parent> obj);
};

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

class ProcessSon: public Process, private Son {
public:
  void SpecificProc1(shared_ptr<Parent> obj) {
    // Make this part of the process based on class Son
  }

  void SpecificProc2(shared_ptr<Parent> obj) {
    // Make this part of the process based on class Son
  }
  ...
};

Сделайте аналогичное для Daughter и отправьте соответствующий Process вместе с указателем на класс в метод process из Director.

...