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

реализация класса "симметричная матрица целых чисел"... - C++

Восстановить пароль Регистрация
 
gudzon
0 / 0 / 0
Регистрация: 07.03.2011
Сообщений: 7
07.03.2011, 18:51     реализация класса "симметричная матрица целых чисел"... #1
Условие вообще такое:

[I]Определите пользовательский тип “симметричная матрица целых чисел” для обработки квадратных матриц, в которых A[i][j] == A[j] для всех допустимых элементов матрицы. Хранить в объекте только верхний треугольник матрицы. Класс должен содержать:
• конструкторы и деструктор;
• конструктор копирования;
• “get” и “set” методы для элементов матрицы;
• “get” метод для размера матрицы;
• операторы сложения и умножения матриц;
• оператор присваивания;
• оператор сравнения ==;
• оператор << для вывода матрицы в указанный поток в обычном виде,
• оператор >> для извлечения матрицы из потока


Но уже на этапе написания конструктора начались проблемы... Если реализация конструктора с хранением значений в нижнем треугольнике мне была еще понятна, то как сделать так, чтобы значения хранились именно в верхнем треугольнике - непонятно... После этого я решил написать программу для начала, работающую с обычными квадратными матрицами, а уже потом под конец внести коррективы для работы с симметричными матрицами, но и там возникли проблемы, вот только на этот раз с деструктором... По каким-то причинам у него нет доступа к матрице и после попытки освободить память вылезает ошибка... Вот код:

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
//matrix.cpp
#include "Matrix.h"
smat::smat(int N, int x){
    n = N;
    int **mat = new int *[N];
    for (int i = 0; i < N; i++){
        mat[i] = new int [N];
        for (int j = 0; j < N; j++)
            mat[i][j] = x;
    }
}
smat::~smat(){
    for (int i = 0; i < n; i++)
        delete mat[i];
    delete [] mat;
}
int smat::get_element(int str, int stb) const{
    if (str < 0 || str > n || stb < 0 || stb > n) throw smat::BadMatrix();
    return mat[str][stb];
}
void smat::set_element(int str, int stb, int x){
    if (str < 0 || str > n || stb < 0 || stb > n) throw smat::BadMatrix();
    mat[str][stb] = x;
}
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//matrix.h
#pragma once
#include <iostream>
using namespace std;
class smat{
    int n, **mat; //n - размер матрицы
public:
    class BadMatrix {};
    smat(int N = 5, int x = 0);
    smat(const smat &M);
    ~smat();
    int get_element(int str, int stb) const;
    void set_element(int str, int stb, int x);
    int get_size() const;
    smat operator + (const smat& M) const;
    smat operator * (const smat& M) const;
    smat& operator = (const smat& M);
    bool operator == (const smat& M) const;
    friend ostream& operator << (ostream& out, const smat& M);
    friend istream& operator >> (istream& in, smat& M);
};
C++
1
2
3
4
5
6
7
8
9
10
11
12
//main.cpp
#include "Matrix.h"
int main(){
    setlocale(LC_ALL, "Rus");
    try{
        smat a;
    }
    catch(...){
        cout << "Ошибка!!\n";
    }
    system("PAUSE");
}
Помогите разобраться по какой причине появляется ошибка доступа к памяти при прохождении деструктора...
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
07.03.2011, 23:18     реализация класса "симметричная матрица целых чисел"... #2
Зачем хранить N^2, когда хватит и половины дозы?
Некоторый функционал.
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
#include <iostream>
#include <algorithm>
#include <iomanip>
#include <ctime>
 
template<class Tp_>
class SymmetricMatrix {
 public:
  explicit SymmetricMatrix(size_t size, Tp_ (*init)(int, int) = NULL)
    : size_(size), data_(NULL) {
    data_ = new Tp_*[size_];
    for (int i = 0; i < size_; ++i) {
      data_[i] = new Tp_[i + 1];
      if (init != NULL)
        for (int j = 0; j < i + 1; ++j)
          data_[i][j] = init(i, j);
    }
  }
  SymmetricMatrix(const SymmetricMatrix &other)
    : size_(other.size_), data_(NULL) {
    CopyFrom(other);
  }
  ~SymmetricMatrix() {
    Clear();
  }
  const Tp_ &At(size_t i, size_t j) const {
    if (j > i) std::swap(i, j);
    return data_[i][j];
  }
  Tp_ &At(size_t i, size_t j) {
    if (j > i) std::swap(i, j);
    return data_[i][j];
  }
  int Size() const {
    return size_;
  }
  void Clear() {
    if (data_ != NULL)
      for (int i = 0; i < size_; ++i)
        delete [] data_[i];
    delete [] data_;
    data_ = NULL;
    size_ = 0;
  }
  void CopyFrom(const SymmetricMatrix &other) {
    Clear();
    size_ = other.size_;
    data_ = new Tp_*[size_];
    for (int i = 0; i < size_; ++i) {
      data_[i] = new Tp_[i + 1];
      for (int j = 0; j < i + 1; ++j)
        data_[i][j] = other.data_[i, j];
    }
  }
  friend std::ostream &operator<<(std::ostream &o,
                                  const SymmetricMatrix &matrix) {
    for (int i = 0; i < matrix.Size(); ++i) {
      for (int j = 0; j < matrix.Size(); ++j)
        o << std::setw(4) << matrix.At(i, j);
      o << std::endl;
    }
    return o;
  }
  SymmetricMatrix &operator=(const SymmetricMatrix &other) {
    if (&other != this)
      CopyFrom(other);
    return *this;
  }
 private:
  size_t size_;
  Tp_** data_;
};
 
int Random(int i, int j) {
  return rand() % 100;
}
 
int main(int argc, char *argv[]) {
  srand(time(NULL));
  SymmetricMatrix<int> matrix(10, Random);
  for (int i = 0; i < matrix.Size(); ++i)
    matrix.At(i, i) = 0;
  std::cout << matrix << std::endl;
}
Добавлено через 1 минуту
А ошибка может быть из-за того, что delete matr[i] вместо delete [] matr[i].
gudzon
0 / 0 / 0
Регистрация: 07.03.2011
Сообщений: 7
07.03.2011, 23:44  [ТС]     реализация класса "симметричная матрица целых чисел"... #3
Спасибо, с ошибкой я уже разобрался, но проблемы на этом не закончились: по-прежнему не понимаю как написать конструктор, создающий матрицу, хранящую значения именно в верхнем треугольнике (но это не главное: для хранения данных в нижнем треугольнике я конструктор написал, если ниче не придумаю и так сойдет)... Куда важнее мне сейчас понять, почему не работает моя реализация перегрузки операции +... Вот код:
C++
1
2
3
4
5
6
7
smat smat::operator+(const smat& M)const{
    smat x(M.size);
    for (int i = 0; i < x.size; i++)
        for (int j = 0; j < i + 1; j++)
            x.mat[i][j] = mat[i][j] + M.mat[i][j];
    return x;
}
Допустим для начала, что суммируемые матрицы одного размера. В приведенной мной выше программе я поле n заменил на size.

Выдает странную ошибку какую-то:
1>main.obj : error LNK2019: unresolved external symbol "public: class smat & __thiscall smat::operator=(class smat const &)" (??4smat@@QAEAAV0@ABV0@@Z) referenced in function _main
1>C:\Users\Владимир2\Documents\Visual Studio 2010\Projects\temp2\Debug\temp2.exe : fatal error LNK1120: 1 unresolved externals
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
07.03.2011, 23:54     реализация класса "симметричная матрица целых чисел"... #4
Цитата Сообщение от gudzon Посмотреть сообщение
по-прежнему не понимаю как написать конструктор, создающий матрицу, хранящую значения именно в верхнем треугольнике
Это условность. Если данные симметричны, верхний треугольник или нижний -- все равно.

Цитата Сообщение от gudzon Посмотреть сообщение
для хранения данных в нижнем треугольнике я конструктор написал
Видимо, код сильно изменился. Надо выложить новый код.

Цитата Сообщение от gudzon Посмотреть сообщение
Выдает странную ошибку какую-то еще на этапе компилляции...
Я буду угадывать ошибку?

Цитата Сообщение от gudzon Посмотреть сообщение
Допустим для начала, что суммируемые матрицы одного размера.
Сферический конь в вакууме. Проверять надо все допущения.
gudzon
0 / 0 / 0
Регистрация: 07.03.2011
Сообщений: 7
08.03.2011, 00:28  [ТС]     реализация класса "симметричная матрица целых чисел"... #5
Цитата Сообщение от lemegeton Посмотреть сообщение
Это условность. Если данные симметричны, верхний треугольник или нижний -- все равно.
Ну, я бы тоже так подумал, но мой преподаватель обратил на это внимание.

Цитата Сообщение от lemegeton Посмотреть сообщение
Видимо, код сильно изменился. Надо выложить новый код.
Возможно, но я думаю в этом уже нет надобности: оказалось надо было просто сначала перегружать оператор =, а затем уже +, а я пытался не перегрузив = посчитать выражение c = a + b;

Цитата Сообщение от lemegeton Посмотреть сообщение
Я буду угадывать ошибку?
Ну я вроде скинул цитатой в предыдущем сообщении то, что VC показывал после компилляции.


Цитата Сообщение от lemegeton Посмотреть сообщение
Сферический конь в вакууме. Проверять надо все допущения.
Обработать исключение, сравнив размеры двух матриц - это 1 строчка кода. Не видел на тот момент смысла останавливаться на этом.
Yandex
Объявления
08.03.2011, 00:28     реализация класса "симметричная матрица целых чисел"...
Ответ Создать тему
Опции темы

Текущее время: 19:41. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru