О боже.Я надеюсь, что вы простите меня, если я буду звучать грубо, но у этого кода есть много проблем, начиная от базового дизайна и заканчивая деталями, такими как циклы, которые вы используете для чтенияданные из файла.
Прежде всего, мне кажется, что вашему классу "матрицы" нужна здоровая доза "единственной ответственности".Я бы сократил его до двухмерной матрицы, ничего больше.
Во-вторых, я бы избавился от управления памятью самостоятельно.Все, что вам действительно нужно, это std::vector
, с достаточным количеством внешнего интерфейса для обеспечения 2D-адресации.
В-третьих, я бы избавился от "getValue" / "setValue" и использовал бы подписку, как и всеПрилично спроектированная матрица, поскольку научные программисты перешли с ассемблера на Фортран в 1950-х годах.
Принимая это во внимание, мы получаем упрощенный класс матрицы, что-то вроде этого:для простоты, когда вы подписываете это, вы используете ()
примерно так же, как в Fortran или BASIC, вместо того, чтобы использовать []
, как вы это обычно делаете в C или C ++.Вы можете поддержать последнее, но это займет намного больше (и уродливее) код .Также обратите внимание, что вы делаете , а не , хотите cols * (y+x)
, вам нужно (cols * y) + x
, если вы настаиваете на использовании скобок (хотя думаете, что это довольно глупо, учитывая, что относительный приоритет умножения и сложения довольно хорошо известен. Наконец,Я сделал этот шаблон просто потому, что это легко сделать - если вы хотите указать тип напрямую, это, очевидно, довольно легко сделать.
Наконец, я бы сделал чтение данных изфайл в матрицу в свободную функцию. При этом я избавлюсь от всех while (!whatever.eof())
, потому что они гарантированно работают неправильно.
template <class T>
void read_matrix(std::string const &filename, matrix<T> &m) {
std::ifstream infile(filename);
std::string line;
int x = 0, y=0;
while (std::getline(infile, line)) {
if (line[0] == '#' || line[0] == ' ')
continue;
int value;
std::istringinstream converter(&line[1]); // &line[1] to skip leading letter
while (converter >> value)
m(x++, y) = value;
++y;
}
}
Технически, &line[1]
не гарантируется работа C ++ 03, но C ++ 11 действительно гарантирует это, в основном потому, что он работает со всеми известными реализациями.