Как: производный член в производном классе с методами, специфичными для производного класса - PullRequest
2 голосов
/ 31 октября 2011

Я использую C ++ под Ubuntu 11.10 и последней версией NetBeans.Допустим, у меня есть следующий код:

class Node {}
class DerivedNode : public Node {}

class Graph {
    vector<Node*> nodes;
}

class DerivedGraph : public Graph { }

В данный момент я храню DerivedNodes в классе DerivedGraph, например, так:

nodes.push_back(new DerivedNode());

Когда мне нужно использовать определенные методыкоторые применяются только к DerivedNodes и DerivedGraphs. Сначала я вынужден использовать dynamic_cast на моих указателях Node.

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

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

РЕДАКТИРОВАТЬ: у меня нет двух копий.Я хотел сделать акцент на том, как это выглядит.Я прошу прощения за презентацию.То, что я хочу получить:

class DerivedGraph: public Graph {
    vector<DerivedNode*> nodes;
}    

Ответы [ 2 ]

1 голос
/ 31 октября 2011

Вы уверены , что ваш интерфейс в Node подходит? Иногда, когда вам необходимо уменьшить (особенно в таком случае, когда базовые указатели хранятся в контейнере), это может быть сигналом того, что ваш абстрактный интерфейс не полностью покрывает все ваши потребности. Часто что-то вроде шаблона Template Method решает все ваши потребности, не требуя принижения вообще.

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

Один из последних подходов состоит в том, чтобы иметь два отдельных контейнера, один в родительском объекте, который содержит все узлы, которые не являются DerivedNode, а затем другой контейнер в DerivedGraph, который содержит все DerivedNode. Затем вы снова используете переопределенные функции, чтобы определить, к какому контейнеру обращаться, в зависимости от потребностей вашего API.

1 голос
/ 31 октября 2011

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

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

Наконец, при переопределении виртуальной функции, которая возвращает ссылку на данные в производном классе, используйте ковариантные типы возврата .

...