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

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

Войти
Регистрация
Восстановить пароль
 
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
#1

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

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

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

Списки. Как правильней организовать? - 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++
Други мои , кодеры. Не могу я ни как передать в функцию объект класса , или что еще лучше(для меня , так как учусь работать с указателями)...

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

Что значит константный указатель на объект, указатель на константный объект, и как это можно использовать? - C++
Подскажите, что значит константный указатель на объект, указатель на константный объект, и как это можно использовать??

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

4
DU
1484 / 1130 / 45
Регистрация: 05.12.2011
Сообщений: 2,279
09.10.2012, 20:25 #2
ну как обычно. написать класс, в котором инкапсулировать все особенности, туда же засунуть все нужные проверки и кидать\возвращать ошибки если клиентский код эти методы начинает вызвать неправильно. написать удобные для клиентского кода функции и радоваться красивому и простому коду.

И кстати вопрос как-то непонятно сформулирован. Не хватает информации.
0
taras atavin
3570 / 1753 / 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;
, но только при равенстве размеров строки и присваиваемого ей массива. При этом присваивание целиком всей матрицы вообще не должно зависеть от совпадения размеров. Как это делается? Я почему то не могу сочинить даже декларацию.
0
DU
1484 / 1130 / 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;
}
1
taras atavin
3570 / 1753 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
10.10.2012, 10:58  [ТС] #5
Идея в подставном классе, экземпляры которого возвращаются по оператору индексации?
0
10.10.2012, 10:58
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
10.10.2012, 10:58
Привет! Вот еще темы с ответами:

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

Может ли объект-член, или объект-элемент достучаться к содержащему его? - C++
Предположим, class A { ... }; class B { .... A a; ... };

интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект - C++
Привет всем. Необходимо реализовать интерфейс, в методе которого создается объект типа IDictionary и возвращается ссылка на этот объект. Не...

Основы: указатель на объект или объект, что выбрать? - C++
Не до конца понимаю (или вообще не понимаю) когда лучше использовать указатель на объект, а когда объект. Например: // есть класс ...


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

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

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