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

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

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

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

20.02.2013, 17:18. Просмотров 853. Ответов 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. Может быть есть другой выход(ы)? Спасибо.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
20.02.2013, 17:18     Классы для работы с двумерными, трехмерными и н-мерными точками
Посмотрите здесь:
C++ Класс Point для работы с точками на плоскости
C++ Создать класс Point для работы с точками на плоскости
Создать класс Point для работы с точками на плоскости C++
Создать класс Point для работы с точками на плоскости C++
C++ Типовые алгоритмы работы с двумерными массивами
C++ Объясните код программы работы с двумерными массивами
Классы для работы с динамическими структурами данных C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Demy85
58 / 58 / 5
Регистрация: 28.05.2012
Сообщений: 211
Завершенные тесты: 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);
    };
};
Данный прием носит название "двойная передача". Конечно есть недостаток - родитель должен знать о потомках.
Аналогично со сложением.

Данный код не проверял, но принцип, думаю, ясен.
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 12:43  [ТС]     Классы для работы с двумерными, трехмерными и н-мерными точками #3
Может еще есть какие то соображения?...
ITcrusader
Эксперт C++
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-мерном пространстве
у тебя будет единственный класс с единственной реализацией, обобщенный по размерности пространства.
Тут же вопрос к знатокам, если таковые сюда заглянут. Целесообразно так делать?
kran69
0 / 0 / 0
Регистрация: 26.02.2013
Сообщений: 9
26.02.2013, 14:05     Классы для работы с двумерными, трехмерными и н-мерными точками #5
а мне интересно, для чего дереференс this сделан? Я понимаю, что возращаеться конкретный объект...но для чего? Лишний стрес на память ведь получаеться - я бы не рисковал и передовал-бы всё через пойнтэр.
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 14:25     Классы для работы с двумерными, трехмерными и н-мерными точками #6
Мне кажется, что модель представления выбрана крайне неудачно.
Если не согласны, давайте подумаем, а чем точка отличается от контейнера? Она хранит набор координат и точки лишь тем и отличаться друг от друга могут, что имеют разную размерность. Плюс, в контексте конкретной задачи ты скорее всего будешь осуществлять взаимодействие между точками одной, фиксированной размерности.

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

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

Обидная бяка с конструкторами, описанная в этом посте чуть выше. Наверняка решаемая с бубном каким-нить)
Поделитесь знаниями!)
djon_tat
0 / 0 / 0
Регистрация: 20.02.2013
Сообщений: 5
26.02.2013, 15:18  [ТС]     Классы для работы с двумерными, трехмерными и н-мерными точками #10
Цитата Сообщение от ITcrusader Посмотреть сообщение
... Я тут подумал, если выбрать подход, основанный на использовании шаблона, то что делать с конструкторами точки? Допустим, я хочу создавать точку, сразу инициализированную координатами отличными от нуля. Как обеспечить такую возможность, учитывая, что для разных n конструктор должен иметь n параметров?))))
Написать конструкторы для двух и трех аргументов явно, а для случая произвольного количества аргументов использовать массивы (контейнеры)...
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 15:36     Классы для работы с двумерными, трехмерными и н-мерными точками #11
Цитата Сообщение от djon_tat Посмотреть сообщение
Написать конструкторы для двух и трех аргументов явно, а для случая произвольного количества аргументов использовать массивы (контейнеры)
Мне кажется, не очень красивое решение, нужно, чтобы способ создания объектов посредством вызова конструктора был унифицирован.
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;
 
}
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
26.02.2013, 16:27     Классы для работы с двумерными, трехмерными и н-мерными точками #13
djon_tat, он не подходит для произвольной размерности. Не, если на практике можно ограничиться размерностью 3, то Бог с ним. Но интереснее же общий случай сделать.

Есть, конеш, variadic templates, но я хз, как с ними сделать, чтобы тип хранимых данных задавался по умолчанию для списка параметров
gray_fox
What a waste!
1411 / 1140 / 55
Регистрация: 21.04.2012
Сообщений: 2,362
Завершенные тесты: 3
26.02.2013, 19:13     Классы для работы с двумерными, трехмерными и н-мерными точками #14
Можно ссылку на массив передать. Ну или initializer_list.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.02.2013, 10:45     Классы для работы с двумерными, трехмерными и н-мерными точками
Еще ссылки по теме:
C++ Расстояние между двумя точками через классы
Классы для работы с данными "Библиотека" C++
C++ Найти максимальное и минимальное значение между точками и вывести их вместе с точками
Работа с трехмерными массивами (векторами) C++
C++ Альтернативные классы и приемы работы

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

Или воспользуйтесь поиском по форуму:
ITcrusader
Эксперт C++
176 / 162 / 8
Регистрация: 12.02.2013
Сообщений: 410
27.02.2013, 10:45     Классы для работы с двумерными, трехмерными и н-мерными точками #15
Цитата Сообщение от gray_fox Посмотреть сообщение
Ну или initializer_list.
В новом стандарте столько вкусностей Которые нельзя юзать(
Yandex
Объявления
27.02.2013, 10:45     Классы для работы с двумерными, трехмерными и н-мерными точками
Ответ Создать тему
Опции темы

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