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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Классы для работы с двумерными, трехмерными и н-ме 
:(
    Опции темы
djontat
Дата 21.2.2013, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Пишу классы для работы с двумерными, трехмерными и n-мерными точками пространства. Решил написать общий базовый класс и от него породить остальные конкретные классы. Получилось пока вот что:

 - базовый абстрактный класс Point

Код

class Point
{
public:
 
virtual ~Point();
 
virtual bool operator==(const Point&) const = 0;
 
virtual const Point& operator+=(const Point&) = 0;
 
...
};

 
- класс двумерных точек Point2D
     
Код

class Point2D: public Point
{
public:
 
Point2D(double x = 0.0, double y = 0.0);
 
~Point2D();
 
void setX(double x);
 
void setY(double y);
 
void set(double x, double y);
 
double x() const;
 
double y() const;
 
bool operator==(const Point2D& point2D) const
{
    return ((m_x == point2D.m_x) && (m_y == point2D.m_y));
};
 
bool operator==(const Point& point) const
{
    return (*this == *dynamic_cast<const Point2D*>(&point));
};
        
const Point2D& operator+=(const Point2D& point)
{
    m_x += point.m_x;
    m_y += point.m_y;
    
    return *this;
};
 
const Point2D& operator+=(const Point& point)
{
    return *this += *dynamic_cast<const Point2D*>(&point);
};
 
...
 
private:
 
double m_x;
 
double m_y;
};


Правильно ли все я написал? Какие подводные камни могут быть в будущем с таким кодом? В частности меня смущает то, что в классе Point2D для каждой операции (в представленном коде для операций == и +=) приходится писать по две функции и одна из функций с использованием dynamic_cast. Может быть есть другой выход(ы)? Спасибо.
PM MAIL   Вверх
Alexeis
Дата 21.2.2013, 14:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  Я бы сказал, что в данной задаче как полиморфизм так и инкапсуляция излишни. Для хранения таких данных будет достаточно простой структуры. С Plain структурами было бы проще манипулировать. Класс удобно было бы создать для объединения точек в более крупные единицы. Например класс меша или контура. А у них уже можно создавать методы для обработки данных. Например поворот контура на некоторый угол или сглаживание или объединение контуров в один общий. 

Это сообщение отредактировал(а) Alexeis - 21.2.2013, 14:27


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
borisbn
Дата 21.2.2013, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



А зачем ? Есть же Boost.Geometry
и ещё штришок...

Цитата(djontat @  21.2.2013,  12:55 Найти цитируемый пост)
 return *this += *dynamic_cast<const Point2D*>(&point);

можно же ссылку кастить
Код
return *this += dynamic_cast<const Point2D&>(point);



--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
djontat
Дата 21.2.2013, 20:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата(borisbn @ 21.2.2013,  18:48)
можно же ссылку кастить

А чем ссылка лучше в этом случае?
PM MAIL   Вверх
borisbn
Дата 21.2.2013, 21:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 4875
Регистрация: 6.2.2010
Где: Ростов-на-Дону

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



> А чем ссылка лучше в этом случае?
Меньше букафф ))) в смысле символов


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
volatile
Дата 22.2.2013, 00:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(borisbn @  21.2.2013,  21:35 Найти цитируемый пост)
Меньше букафф 

Правильно! чем их, меньше тем завсегда оно лучче!

Цитата(djontat @  21.2.2013,  12:55 Найти цитируемый пост)
bool operator==(const Point& point) const
{
    return (*this == *dynamic_cast<const Point2D*>(&point));
};

Код

bool operator == (const Point & point) const
{
   return point == *this;
}

smile 


Это сообщение отредактировал(а) volatile - 22.2.2013, 00:02
PM MAIL   Вверх
mes
Дата 22.2.2013, 09:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


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


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

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



Цитата(volatile @  21.2.2013,  23:00 Найти цитируемый пост)
bool operator == (const Point & point) const
{
   return point == *this;
}


Карусель, карусель!
Это радость для нас.
Прокатись на нашей карусели!
Ля-ля-ля!....
 smile

Добавлено через 2 минуты и 54 секунды
Цитата(borisbn @  21.2.2013,  20:35 Найти цитируемый пост)
А чем ссылка лучше в этом случае?
Меньше букафф ))) в смысле символов 

исключением smile


Цитата(djontat @  21.2.2013,  11:55 Найти цитируемый пост)
== *dynamic_cast<const Point2D*>(&point));


djontat, а если point не Point2d ? 

и да с полиморфизмом намудрено.. пользоваться полученным будет имхо затруднительно..



--------------------
PM MAIL WWW   Вверх
baldina
Дата 22.2.2013, 11:17 (ссылка) |    (голосов:3) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(djontat @  21.2.2013,  12:55 Найти цитируемый пост)
Пишу классы для работы с двумерными, трехмерными и n-мерными точками пространства. Решил написать общий базовый класс и от него породить остальные конкретные классы

для каждого n собираешься класс порождать? 
шаблон+stl

Код

template <size_t N>
struct Point {

  double data[N];

  Point () {
     std::fill (data, data+N, 0.0);
  }

  template <size_t M>
  Point (const Point<M> other) {
     size_t size = std::min(N,M);
     std::copy (other.data, other.data+size, data);
     std::fill (data+size, data+N, 0.0);
  }

  double operator[] (size_t i) const { return data[i]; }
  double& operator[] (size_t i) { return data[i]; }

  bool operator==(const Point& other) {
     return std::equal (data, data+N, other, [](double *x, double *y) { return std::abs(*x-*y) < epsilon; });
  }

  Point& operator+=(const Point& other) {
    std::transform (other.data, other.data+N, data, data, std::plus<double>());
    return *this;
  }
};

PM MAIL   Вверх
djontat
Дата 25.2.2013, 16:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

djontat, а если point не Point2d ? 


например, для Point3D планируется оператор приведения в Point2D, путем отсечения третей координаты 

Цитата

для каждого n собираешься класс порождать? 


нет, не для каждого, планирую всего три класса: Point2D, Point3D, PointND.

По поводу намудренности с полиморфизмом и по поводу шаблон+stl: далее планирую классы такие как например отрезки (в двумерном, трехмерном и н-мерном пространстве) 

Код

class Segment
{
public:
 ...
 
private:
 
Point* m_a, m_b;
};


и т.д.
PM MAIL   Вверх
baldina
Дата 25.2.2013, 18:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



для использования точек в отрезках полиморфизм вобщем-то не нужен.
Цитата(djontat @  25.2.2013,  16:55 Найти цитируемый пост)
 планирую всего три класса: Point2D, Point3D, PointND.

PointND это интересно. Понятно, что имея PointND, он легко используется в качестве 2d или 3d.

Фактически, такой класс с использованием stl написан выше.
2d и 3d будут выглядеть как
Код

typedef Point<2> Point2D;
typedef Point<3> Point3D;


Цитата(djontat @  25.2.2013,  16:55 Найти цитируемый пост)
например, для Point3D планируется оператор приведения в Point2D, путем отсечения третей координаты 

посмотри на конструктор
Код

template <size_t M>
Point (const Point<M> other)

с его помощью может производиться и усечение, и расширение размерности.

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

Добавлено через 9 минут
еще хочу спросить:
Цитата(djontat @  25.2.2013,  16:55 Найти цитируемый пост)

class Segment {
 ...
Point* m_a, m_b;
...
};


Point, как я понимаю, у тебя базовый класс? Как будет обеспечиваться согласованность размерности m_a и m_b?
Зачем вообще иметь Segment с концами обобщенной размерности? Все фигуры будут жить в пространстве одной размерности. 
PM MAIL   Вверх
djontat
Дата 26.2.2013, 11:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



Цитата

PointND это интересно. Понятно, что имея PointND, он легко используется в качестве 2d или 3d.

PointND - это и есть класс точек с произвольной размерностью (включая 2 и 3 мерность). Решил выделить 2D и 3D в отдельные классы только ради эффективности.

Такой код
Код

class Segment {
 ...
Point* m_a, m_b;
...
};

планирую чтобы не нужно было вводить отдельно Segment2D и Segment3D. 

А насчет
Цитата

Point, как я понимаю, у тебя базовый класс? Как будет обеспечиваться согласованность размерности m_a и m_b?
Зачем вообще иметь Segment с концами обобщенной размерности? Все фигуры будут жить в пространстве одной размерности. 
 
хороший вопрос...

Против шаблонов+stl ничего против не имею. В этом случае наверно придется делать след. образом
Код

template <size_t N>
class Segment 
{
    Point m_a<N>;
    Point m_b<N>;
 };

Правильно я понимаю? какие минусы в таком случае?
PM MAIL   Вверх
djontat
Дата 26.2.2013, 12:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



По поводу
Цитата

Point, как я понимаю, у тебя базовый класс? Как будет обеспечиваться согласованность размерности m_a и m_b?
Зачем вообще иметь Segment с концами обобщенной размерности? Все фигуры будут жить в пространстве одной размерности. 

Если в классе Point ввести метод size(), который возвращает размерность точки, а потом в конструкторе Segment проверять равенство размерности точек конца отрезка....
PM MAIL   Вверх
baldina
Дата 26.2.2013, 14:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(djontat @  26.2.2013,  11:39 Найти цитируемый пост)
Решил выделить 2D и 3D в отдельные классы только ради эффективности.

такое решение называется преждевременная оптимизация
думается мне, вышеупомянутый функционал сделать эффективнее для частного случая, чем в моём обобщенном примере, не удастся: сейчас компиляторы очень неплохо оптимизируют, например для 2 и 3D циклы наверняка будут развернуты.

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

Цитата(djontat @  26.2.2013,  11:39 Найти цитируемый пост)
Правильно я понимаю? какие минусы в таком случае? 

правильно. минусов я не вижу (по крайней мере не видя всю задачу, т.е. для чего это делается)

Цитата(djontat @  26.2.2013,  12:34 Найти цитируемый пост)
Если в классе Point ввести метод size(), который возвращает размерность точки, а потом в конструкторе Segment проверять равенство размерности точек конца отрезка.... 

т.е. создать себе трудности что бы потом их героически преодолевать? имхо лучше их просто не создавать...

PM MAIL   Вверх
baldina
Дата 26.2.2013, 15:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(djontat @  26.2.2013,  11:39 Найти цитируемый пост)
template <size_t N>
class Segment 
{
    Point m_a<N>;
    Point m_b<N>;
 };

только конечно
Код

Point<N> m_a;

PM MAIL   Вверх
djontat
Дата 26.2.2013, 18:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



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

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



В случае шаблонного класса что делать с конструкторами точки? Допустим, я хочу создавать точку, сразу инициализированную координатами отличными от нуля. Как обеспечить такую возможность, учитывая, что для разных n конструктор должен иметь n параметров?
PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

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

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


 




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


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

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