C ++ меняет член производного класса на его специализированную версию - PullRequest
0 голосов
/ 21 ноября 2018

Допустим, у меня есть два класса - Graph и Vertex , которые имеют некоторые базовые члены и методы, необходимые для представления общего Graph.Они уже полностью реализованы и отлично работают для стандартных графов.

class Vertex { 
    int id;
    Vertex(int id) : id(id) {}
    // ...
}

class Graph {
    std::vector<Vertex *> vertices;
    void addVertex(int id) {
        vertices.push_back(new Vertex(id));
    }
    // ...
}

И я хотел бы расширить эти классы, чтобы добавить некоторые функциональные возможности, связанные с проблемами.Например, я хочу иметь Вершина , которая хранит его цвет.Вот почему я объявляю другой класс с именем VertexC , который наследуется от Vertex и добавляет новый член.Так что теперь я хотел бы иметь специализированную версию Graph - GraphC , которая может управлять новыми VertexC свойствами.

class VertexC: Vertex {
    string colour;
    string getColour() {
        return colour;
    }
}

class GraphC: Graph {
    void doSomething(string colour) {
        for(auto &v: vertices) {
            if(v->getColour() == "red") // Do something...
        }
    }
}

Но яне может сделать это, потому что Graph :: vertices имеют тип Vertex *, а не VertexC *, поэтому они не имеют getColour () метод.Любые предложения, как преодолеть это?

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

1 Ответ

0 голосов
/ 21 ноября 2018

Один из вариантов - шаблон класса Graph.Что-то вроде:

template<typename TVert> class Graph
{
    std::vector<TVert> vertices;
    // ...
};

, что означает, что специализация может быть объявлена ​​как:

class GraphC : public Graph<VertexC*>
{
    // ...
};

Что-то может потребоваться сделать с методом addVertex.Он может быть объявлен следующим образом:

void addVertex(int id)
{
    vertices.push_back(new TVert(id));
}

Хотя это будет означать, что любые специализации класса Graph должны иметь только те типы, которые включают конструктор, который принимает один аргумент int.Альтернативой может быть что-то вроде:

void addVertex(TVert vert)
{
    vertices.push_back(vert);
}

Обратите внимание также на добавление ключевого слова public в объявлении класса GraphC.Это необходимо для того, чтобы сделать метод addVertex в Graph доступным через экземпляры GraphC.

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