Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
#1

Классы для работы с двумерными, трехмерными и н-мерными точками - C++

20.02.2013, 17:18. Просмотров 891. Ответов 14
Метки нет (Все метки)

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

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

C++
1
2
3
4
5
6
7
8
9
10
11
12
class Point
{
public:
 
virtual ~Point();
 
virtual bool operator==(const Point&) const = 0;
 
virtual const Point& operator+=(const Point&) = 0;
 
...
};
- класс двумерных точек Point2D

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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. Может быть есть другой выход(ы)? Спасибо.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.02.2013, 17:18
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Классы для работы с двумерными, трехмерными и н-мерными точками (C++):

Класс Point для работы с точками на плоскости - C++
Создать класс Point для работы с точками на плоскости. Координаты точки –декартовы. Обязательно должны быть реализованы: перемещение точки...

Создать класс Point для работы с точками на плоскости - C++
помогите пожалуйста,очень нужно. Создать класс Point для работы с точками на плоскости. Координаты точки – декартовы. • перемещение...

Создать класс Point для работы с точками на плоскости - C++
Задания должны быть реализованы двумя способами: - тип данных представляется структурой с необходимыми полями, а операции реализуются как...

Создать класс Point для работы с точками на плоскости - C++
Прошу помощи, только третья лаба по классам. Не совсем понимаю (может даже вообще) как это делать. Прошу указать и объяснить ошибки. И...

Типовые алгоритмы работы с двумерными массивами - C++
Добрый день. Нужна помощь до завтра!Перевести на язык С++\\ просто это походу паскаль. на С++ не могу найти инфу Типовые алгоритмы...

Объясните код программы работы с двумерными массивами - C++
#include &lt;time.h&gt; #include &lt;stdlib.h&gt; #include &lt;iostream&gt; #include &lt;cmath&gt; #include &lt;iomanip&gt; using namespace std; const int...

14
Demy85
59 / 59 / 5
Регистрация: 28.05.2012
Сообщений: 220
Завершенные тесты: 1
20.02.2013, 18:37 #2
Есть более интересный способ:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Point
{
protected:
    virtual bool operator ==(const Point2D &point) const;   
public:
    virtual bool operator==(const Point&) const = 0;
};
 
class Point2D: public Point
{
public:
    bool operator==(const Point2D& point2D) const
    {
        return ((m_x == point2D.m_x) && (m_y == point2D.m_y));
    };
     
    bool operator==(const Point& point) const
    {
        return (point == *this);
    };
};
Данный прием носит название "двойная передача". Конечно есть недостаток - родитель должен знать о потомках.
Аналогично со сложением.

Данный код не проверял, но принцип, думаю, ясен.
1
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 12:43  [ТС] #3
Может еще есть какие то соображения?...
0
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 13:59 #4
Еще соображение, пока первые строки кода только прочитал, НО!!!
C++
1
virtual const Point& operator+=(const Point&) = 0;
в возвращаемом значении убери константность, для встроенных типов работает следующий код:
C++
1
( a+=10 ) += 10;
для твоих точек он работать не буит. Старина Бьерн дал тебе возможность определять пользовательские типы, практически неотличимые от встроенных. Не разочаровывай его

Добавлено через 6 минут
Вдогонку) А когда тебе понадобится n-мерная точка? Будешь создавать еще один потомок? И да, перепиливать реализацию снова. Мне кажется, класс точки можно было бы сделать шаблонным, в качестве шаблона передавать размерность

C++
1
2
3
4
5
6
template <class int = 1>
class Point 
{
};
 
Point<3> a; // точка в 3-мерном пространстве
у тебя будет единственный класс с единственной реализацией, обобщенный по размерности пространства.
Тут же вопрос к знатокам, если таковые сюда заглянут. Целесообразно так делать?
0
kran69
0 / 0 / 0
Регистрация: 26.02.2013
Сообщений: 9
26.02.2013, 14:05 #5
а мне интересно, для чего дереференс this сделан? Я понимаю, что возращаеться конкретный объект...но для чего? Лишний стрес на память ведь получаеться - я бы не рисковал и передовал-бы всё через пойнтэр.
0
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 14:25 #6
Мне кажется, что модель представления выбрана крайне неудачно.
Если не согласны, давайте подумаем, а чем точка отличается от контейнера? Она хранит набор координат и точки лишь тем и отличаться друг от друга могут, что имеют разную размерность. Плюс, в контексте конкретной задачи ты скорее всего будешь осуществлять взаимодействие между точками одной, фиксированной размерности.

Давайте шаблонизируемся?
0
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 14:48  [ТС] #7
Цитата Сообщение от ITcrusader Посмотреть сообщение
Мне кажется, что модель представления выбрана крайне неудачно.
Если не согласны, давайте подумаем, а чем точка отличается от контейнера? Она хранит набор координат и точки лишь тем и отличаться друг от друга могут, что имеют разную размерность. Плюс, в контексте конкретной задачи ты скорее всего будешь осуществлять взаимодействие между точками одной, фиксированной размерности.

Давайте шаблонизируемся?
Вы предлагаете что-то в таком виде?

C++
1
2
3
4
5
6
7
template <size_t n>
class Point 
{
private:
  double data[n];
...
};
А что если для размерности ввести еще один параметр в классе (вместо параметра шаблона) и задавать его через конструктор? В чем плюсы и минусы этих двух подходов?

Добавлено через 11 минут
И еще, есть ли смысл, с точки зрения эффективности, в выделении классов 2 и 3-х мерных точек?
0
kran69
0 / 0 / 0
Регистрация: 26.02.2013
Сообщений: 9
26.02.2013, 14:50 #8
Хм, основываясь на данной информации, склоняюсь к точке зрения ITcrusaderа. Хоть что наследственность, что тэмплэйты поддерживают интерфэйс и полиморфизм - в данном случае, как я понял, вся иерархия заключаеться что есть родитель Point и его дети, которым по-сути не обязательно знать о своём предке или других сибсов. В таком случае, имеет смысл использывать шаблоны, разве нет?
0
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 15:16 #9
djon_tat, да, только я подумывал использовать, например, valarray, вроде бы эта штука оптимизирована для выполнения однотипных мат. операций над элементами, ну и имеет конструктор, деструктор и множество своих функций, которые, быть может, будут полезны в работе. Но это мелочи жизни. Я тут подумал, если выбрать подход, основанный на использовании шаблона, то что делать с конструкторами точки? Допустим, я хочу создавать точку, сразу инициализированную координатами отличными от нуля. Как обеспечить такую возможность, учитывая, что для разных n конструктор должен иметь n параметров?))))

Добавлено через 17 минут
Цитата Сообщение от djon_tat Посмотреть сообщение
А что если для размерности ввести еще один параметр в классе (вместо параметра шаблона) и задавать его через конструктор? В чем плюсы и минусы этих двух подходов?
Главный плюс шаблона здесь - статическое связывание типа с цифрой. Т.е. Если ты инстанцировал точку 2d, то не сможешь к ней прибавлять точку из 3d, так как они разных типов и это будет обнаружено на этапе компиляции.
Ежели ты будешь размерность хранить как поле класса, то у тебя будет по сути один класс - точка n-мерная. И придется осуществлять контроль размерностей в операциях.

Обидная бяка с конструкторами, описанная в этом посте чуть выше. Наверняка решаемая с бубном каким-нить)
Поделитесь знаниями!)
0
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 15:18  [ТС] #10
Цитата Сообщение от ITcrusader Посмотреть сообщение
... Я тут подумал, если выбрать подход, основанный на использовании шаблона, то что делать с конструкторами точки? Допустим, я хочу создавать точку, сразу инициализированную координатами отличными от нуля. Как обеспечить такую возможность, учитывая, что для разных n конструктор должен иметь n параметров?))))
Написать конструкторы для двух и трех аргументов явно, а для случая произвольного количества аргументов использовать массивы (контейнеры)...
0
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 15:36 #11
Цитата Сообщение от djon_tat Посмотреть сообщение
Написать конструкторы для двух и трех аргументов явно, а для случая произвольного количества аргументов использовать массивы (контейнеры)
Мне кажется, не очень красивое решение, нужно, чтобы способ создания объектов посредством вызова конструктора был унифицирован.
0
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 16:10  [ТС] #12
А чем такой конструктор не нравится
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
Point(double x = 0.0, double y = 0.0, double z = 0.0)
{
   if (n < 2)
     data[0] = x;
   if (n < 3)
     data[1] = y;
   if (n < 4)
     data[2] = z;
 
   for (i = 3; i <= n; i++)
     d[i] = 0.0;
 
}
0
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 16:27 #13
djon_tat, он не подходит для произвольной размерности. Не, если на практике можно ограничиться размерностью 3, то Бог с ним. Но интереснее же общий случай сделать.

Есть, конеш, variadic templates, но я хз, как с ними сделать, чтобы тип хранимых данных задавался по умолчанию для списка параметров
0
gray_fox
What a waste!
1521 / 1226 / 70
Регистрация: 21.04.2012
Сообщений: 2,565
Завершенные тесты: 3
26.02.2013, 19:13 #14
Можно ссылку на массив передать. Ну или initializer_list.
1
ITcrusader
Эксперт С++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
27.02.2013, 10:45 #15
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну или initializer_list.
В новом стандарте столько вкусностей Которые нельзя юзать(
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2013, 10:45
Привет! Вот еще темы с ответами:

Классы для работы с динамическими структурами данных - C++
Задали такую задачу, сделал почти все лабы из этой главы, но вот эт и еще одну никак не могу понять... не понимаю что имеется ввиду под...

Расстояние между двумя точками через классы - C++
Здравствуйте. Требуется написать программу, которая вычисляет расстояние между двумя введёнными точками на плоскости, используя классы. ...

Классы для работы с данными "Библиотека" - C++
Нужно сделать задачу по классам, HELP! :cry: Создайте программу с классом Bibliographer, который включает в себя следующие...

Работа с трехмерными массивами (векторами) - C++
Доброго времени суток, помогите пожалуйста разобраться с работой с трехмерными массивами. Есть задачка: пятнашки, поле 3х3 1 8 4 6...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Yandex
Объявления
27.02.2013, 10:45
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru