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

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

Войти
Регистрация
Восстановить пароль
 
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

Как правильней делать матрицу-объект? - C++

09.10.2012, 20:20. Просмотров 425. Ответов 4
Метки нет (Все метки)

Сделать динамический одномерный массив - не проблема, проблема в том, что матрица должна быть строго прямоугольной, а состоять из массивов. А если написать
C++
1
m[2]=v;
, где v - одномерный массив, а m - матрица с числом столбцов, отличным от числа элементов v? Или
C++
1
m[3].resize(10);
? Вот это и вызывает вопросы.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
09.10.2012, 20:20     Как правильней делать матрицу-объект?
Посмотрите здесь:

Списки. Как правильней организовать? - C++
Вот текст программы #include <iostream> #include <conio.h> #include <ctime> #include <cstdlib> #include <windows.h> using...

Как правильней объявить динамический двухмерный массив - C++
Как правильней объявить динамический двухмерный массив и почему int (*p) = new int; //Или int **p = new int * ; for (int i =...

Какой вариант конструктора использовать правильней? - C++
Два примера кода, какой из них использовать более корректно и профессионально? 1) card(){ } card (deck_1 value_1, deck_2...

Как умножить матрицу на матрицу? - C++
Как умножить матрицу на матрицу? Напишите пожалуйста!

Как умножить матрицу на матрицу - C++
Как умножить матрицу на матрицу в Visual Studio?

Как делать правильнее? - C++
Есть класс, допустим, "Фигура" class Shape { protected: int xpos; int ypos; public: /* Здесь деструкторы и...

как это делать? - C++

как делать трассировку? - C++
не получается нормально сделать трассировку. помогите. надо уложиться в 50 строк, избегая ввода и вывода переменных. //...

Подскажите как делать,пожалуйста - C++
Вот задачка,сколько сижу думаю над ней,не понимаю=( 1)Соседями элементами Аij в матрице назовем элементы Аkl(внизу) c...

Как делать log.txt? - C++
Реализацию объяснять не надо - сам справлюсь. А что выводу в лог подлежит и где именно этот вывод лучше сделать?


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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
09.10.2012, 20:25     Как правильней делать матрицу-объект? #2
ну как обычно. написать класс, в котором инкапсулировать все особенности, туда же засунуть все нужные проверки и кидать\возвращать ошибки если клиентский код эти методы начинает вызвать неправильно. написать удобные для клиентского кода функции и радоваться красивому и простому коду.

И кстати вопрос как-то непонятно сформулирован. Не хватает информации.
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
09.10.2012, 20:37  [ТС]     Как правильней делать матрицу-объект? #3
Надо реализовать класс строго прямоугольного динамического массива и перегрузить операции сложения, вычитания и умножения, написать методы, возвращающие: определитель, обратную матрицу, транспонированную матрицу. Ресайз строки должен быть закрыт, но элемент адресоваться в через два индеса, то есть, например,
C++
1
x=m[2][6];
. При этом у матрица в целом ресайз должен быть открыт, например,
C++
1
m.resize(10, 20);
должен менять и количество строк на 10 и длины всех строк на 20. Адресация в один индекс, например,
C++
1
r=m[8];
должна возвращать строку-объект. Надо поддерживать присваивание сразу всей строки, например,
C++
1
m[8]=r;
, но только при равенстве размеров строки и присваиваемого ей массива. При этом присваивание целиком всей матрицы вообще не должно зависеть от совпадения размеров. Как это делается? Я почему то не могу сочинить даже декларацию.
DU
1480 / 1056 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
09.10.2012, 21:39     Как правильней делать матрицу-объект? #4
Вот если в кратце то так:
Завести класс строк, класс ссылок на строк и класс матрицы.
матрица будет возвращать ссылочные строки, которые не позволяют изменять реальные строки, на которые они ссылаются. этим самым будет невозможен такой код: m[i].resize();
При этом снабдить всех правильными конструкторами и операторами =, чтобы были проверки и работало согласно требованиям.
Вот в быстренькое решение на коленке со своими проблемами . неконстантность оператора [], нужно следить за протуханием ссылочных строк и прочее. но для точки отсчета должно пригодится:

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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <vector>
 
template <typename T>
class Row;
 
template <typename T>
class RowRef;
 
 
template <typename T>
class Row
{
public:
  Row()
  {
  }
 
  Row(const RowRef<T>& rowRef);
  Row& operator = (const RowRef<T>& rowRef);
 
  const T& operator [] (unsigned index) const
  {
    return m_data[index];
  }
 
  T& operator [] (unsigned index) 
  {
    return m_data[index];
  }
 
  unsigned getSize() const
  {
    return static_cast<unsigned>(m_data.size());
  }
 
  void resize(unsigned size)
  {
    // тут нужна более умная реализация, позволяющая уменьшать размеры
    // и сохраняющая или не сохраняющая уже имеющиеся данные.
    m_data.resize(size);
  }
 
private:
  std::vector<T> m_data;
};
 
 
template <typename T>
class RowRef
{
public:
  explicit RowRef(Row<T>& row)
    : m_row(&row)
  {
  }
 
  RowRef& operator = (const Row<T>& row)
  {
    if (m_row->getSize() == row.getSize())
    {
      *m_row = row;
    }
    return *this;
  }
 
  const T& operator [] (unsigned index) const
  {
    return (*m_row)[index];
  }
 
  T& operator [] (unsigned index) 
  {
    return (*m_row)[index];
  }
 
  unsigned getSize() const
  {
    return m_row->getSize();
  }
 
private:
  Row<T>* m_row;
};
 
 
template <typename T>
Row<T>::Row(const RowRef<T>& rowRef)
  : m_data(&rowRef[0], &rowRef[0] + rowRef.getSize())
{
}
 
template <typename T>
Row<T>& Row<T>::operator = (const RowRef<T>& rowRef)
{
  m_data.assign(&rowRef[0], &rowRef[0] + rowRef.getSize());
  return this;
}
 
 
template <typename T>
class Matrix
{
public:
  // Проблема. С помощью возвращенной ссылки можно поменять строку. Нужно возвращать что-то, через что это сделать нельзя.
  RowRef<T> operator [] (unsigned index) const
  {
    return RowRef(m_rows[index]);
  }
 
  RowRef<T> operator [] (unsigned index) 
  {
    return RowRef<T>(m_rows[index]);
  }
 
  void resize(unsigned rows, unsigned columns)
  {
    // тут нужна более умная реализация, позволяющая уменьшать размеры
    // и сохраняющая или не сохраняющая уже имеющиеся данные.
    m_rows.resize(rows);
    for (std::vector< Row<T> >::iterator it = m_rows.begin(), end = m_rows.end(); it != end; ++it)
    {
      it->resize(columns);
    }
  }
 
  unsigned getRows() const
  {
    return m_rows.size();
  }
 
  unsigned getColumns() const
  {
    return m_rows.empty() ? 0 : m_rows[0].getSize();
  }
 
private:
  std::vector< Row<T> > m_rows;
};
 
 
 
int main()
{
  Matrix<int> m;
  m.resize(5, 5);
  m[1][1] = 10;
//  m[1].resize(10); // это не компилится. потому что возвращается RowRef у которого нет метода ресайза
  Row<int> r = m[1]; // ok. у Row есть конструктор, который принимает RowRef и копирует в себя все данные из ссылочной строки.
  m[1] = r; // RowRef имеет оператор =, который копирует из r данные если размеры строк совпадают.
  r.resize(10); // это можно ресайзить, потому что это копия строки из матрицы. все изменения с этой строкой не влияют на размеры и значения исходной матрицы
  m[1] = r; // не пройдет. разные размеры у матричной строки и у этой копии.
 
  return 0;
}
taras atavin
Ушёл с форума.
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
10.10.2012, 10:58  [ТС]     Как правильней делать матрицу-объект? #5
Идея в подставном классе, экземпляры которого возвращаются по оператору индексации?
Yandex
Объявления
10.10.2012, 10:58     Как правильней делать матрицу-объект?
Ответ Создать тему
Опции темы

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