Модераторы: bsa
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> наследование по правилам? 
:(
    Опции темы
teanik
Дата 15.12.2009, 21:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 15.12.2009

Репутация: нет
Всего: нет



Здравствуйте. Я с трудом переезжаю с С на С++, поэтому, пожалуйста, объясните как тупому чайнику.
Есть базовые классы для описания графа (вершины, направленные ребра):
Код

class Vertex {
public:
  Vertex(double x, double y);
  ~Vertex();
  //get and set classes
  ...
protected:
  double x;
  double y;
  Edge* outEdge;
};

class Edge {
public:
  Edge();
  ~Edge();
  //get and set classes
  ...
protected:
  Vertex* origin;
  Edge* twin;
  Edge* next;
  Edge* prev;
};

class Graph {
public:
  Graph();
  ~Graph();
  Vertex* insertVertex(double x, double y);
  Edge* connectVertices(Vertex* v1, Vertex* v2);
  //и т.д.
  ...
protected:
  vector<Vertex*> vertices;
  vector<Edge*> edges;
}


Требуется расширить эти объекты до class DVertex, DEdge, DGraph. Как можно в DGraph переиспользовать метод Graph::connectVertices(Vertex* v1, Vertex* v2) (который создает новый объект Edge)? Нужно, чтобы DGraph::connectVertices(DVertex* v1, DVertex* v2) создавал и возвращал новый класс. Вообще, как в моем случае писать базовые классы "по правилам", чтобы при наследовании не возникало проблем с инициализацией новых объектов?

Есть идея вынести создание объекта Edge из метода connectVertices и передавать пустой объект в него как параметр. Но, по-моему, это через одно место :-\

Спасибо!
PM MAIL   Вверх
baldina
Дата 15.12.2009, 23:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3433
Регистрация: 5.12.2007
Где: Москва

Репутация: 15
Всего: 101



1й способ
Код

class Vertex;
class Edge {
...
 Edge (Vertex*, Vertex*);
...
};

class Graph {
...
virtual Edge *createEdge (Vertex* v1, Vertex *v2) { return new Edge (v1, v2); }
...
};

class DEdge : public Edge {...};
class DGraph : public Graph {
...
virtual Edge *createEdge (Vertex* v1, Vertex *v2) { return new DEdge (v1, v2); }
...
};


2й способ
Код

template <typename T>
class Edge {...};

template <typename T>
class Vertex {...};

template <typename T>
class Graph {
...
Edge<T> *createEdge (Vertex<T>* v1, Vertex<T> *v2) { return new Edge<T> (v1, v2); }
...
};

class D {...};

typedef Graph<D> DGraph;


а вообще
Цитата

Требуется расширить эти объекты до class DVertex, DEdge, DGraph.

нет ли здесь логической ошибки, избыточности? операции на графе не зависят от дополнительной атрибутивной информации, которую можно приписать графу, ребру, вершине. Чем DEdge отличается от Edge? 
если действительно нужно иметь семейство классов, то см. способ 2
PM MAIL   Вверх
teanik
Дата 16.12.2009, 00:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 15.12.2009

Репутация: нет
Всего: нет



Спасибо за советы.

1й способ предполагает оверлоад метода? То есть по сути переписывать все функциональности заново? (Там дело в том, что метод не просто создает новый объект, а производит кучу дополнительных проверок -- пересечения ребер и т.п.)

по 2му способу такой вопрос
Базовые классы изначально не предполагались для дальнейшей переработки. По сути они описывают цельную структуру. В большинстве приложений они будут использоваться как есть. В моем случае мне надо расширить их до разбиения карты местности на регионы со всякими вытекающими оттуда параметрами с дополнительными функциональностями. То есть без расширения классов не обойтись. Использование template здесь единственный метод?

PM MAIL   Вверх
bsa
Дата 16.12.2009, 01:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



teanik, может стоит книжку по С++ почитать? Ты просто не понимаешь основ объектно-ориентированного программирования. В частности, никто не заставляет тебя переписывать методы полностью - всегда есть возможность вызова методов базового класса (используя такую запись: Base::method()). Более того, чтобы не переписывать всю функциональность нужно изначально проработать классы грамотно. Скорее всего, правильно будет выбрать вообще другие основы для классов, а не Edge, Vertex и Graph
PM   Вверх
teanik
Дата 16.12.2009, 20:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 15.12.2009

Репутация: нет
Всего: нет



Конечно стоит! smile
Я, разумеется, не имел в виду переписывать все-все методы, и про вызов методов базового класса, большое спасибо, я в курсе.
Но, если метод класса Graph создает новый объект Edge, то не вижу другого метода добиться создания объекта DEdge в классе DGraph, как переписать этот метод заново.

Цитата

Более того, чтобы не переписывать всю функциональность нужно изначально проработать классы грамотно.


В этом и был вопрос. Как проработать классы грамотно?
PM MAIL   Вверх
mes
Дата 16.12.2009, 22:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

Репутация: 79
Всего: 250



Цитата(teanik @  16.12.2009,  19:55 Найти цитируемый пост)
В этом и был вопрос. Как проработать классы грамотно? 


Цитата(teanik @  16.12.2009,  19:55 Найти цитируемый пост)
Но, если метод класса Graph создает новый объект Edge, то не вижу другого метода добиться создания объекта DEdge в классе DGraph, как переписать этот метод заново.

если мы не знаем чем DEdge отличается от Edge, то как можно что то советовать ?

если нужны замечания по приведенному коду, то
Код

class Vertex {
  ...
protected:
  double x;
  double y;
  Edge* outEdge; //  точка по идеи не должна зависить от ребра.
};

class Edge {
  ...
protected:
  Vertex* origin; 
  Edge* twin;
  Edge* next;   
  Edge* prev;  // также зачем напрягать ребра знанием друг о друге, когда для этого есть список.
};
class Graph {

  ...
protected:
  vector<Vertex*> vertices; // а зачем хранить точки, если ребро их хранит ?
  vector<Edge*> edges;       
}


имхо, прежде чем расширять до D.. стоит внимательно пересмотреть текущее.

Это сообщение отредактировал(а) mes - 16.12.2009, 22:41


--------------------
PM MAIL WWW   Вверх
teanik
Дата 17.12.2009, 00:43 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 6
Регистрация: 15.12.2009

Репутация: нет
Всего: нет



Классы Vertex, Edge (и там еще есть Face) образуют такую структуру, как Doubly Connected Edge List (это из вычислительной геометрии).  Ссылки у вершин, ребер и граней друг на друга нужны для ускорения выполнения запросов. Структура эта, как говорится, широко известна в узких кругах. Класс Graph как раз и представляет из себя Doubly Connected Edge List и содержит списки имеющихся вершин, ребер и граней, а также методы их добавления и удаления.

Нужен способ динамического разбиения плоскости (карты) на регионы со всякими параметрами, типа кол-во населения и т.п. Плотность населения представлена потоками и меняется со временем. Идея была это сделать на базе DCEL. Классы DVertex, DEdge, DFace будут иметь дополнительные поля (такие, как время последнего изменения, вес по плотности населения и т.д) DGraph должен связать DCEL и объекты, описывающие окружающую среду.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.0880 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.