Переопределение операций. Организация потокового ввода-вывода, страница 2

      p=(pp>0)?pp:1;// скорректировать порядок, если он указан неверно

      k=new double*[p];// создать массив строк коэффициентов

      for(int i=0;i<p;i++){

            k[i]=new double[p];// создать i-ю строку

            for(int j=0;j<p;j++) k[i][j]=val;// все коэффициенты в ней инициализировать нужным значением

      }

}

// конструктор копирования

smatrix::smatrix(const smatrix& m){

      p=m.p;// скопировать порядок матрицы

      k=new double*[p];// создать массив строк коэффициентов

      for(int i=0;i<p;i++){// скопировать коэффициенты из переданного объекта

            k[i]=new double[p];

            for(int j=0;j<p;j++) k[i][j]=m.k[i][j];

      }

}

smatrix::~smatrix(){// деструктор

      for(int i=0;i<p;i++) delete []k[i];// удалить все строки коэффициентов

      delete []k;// удалить массив строк

}

// ввод коэффициентов

void smatrix::enter(char* mn){

      cout << "Enter " << mn << endl;

      for(int i=0;i<p;i++){// пройти весь массив коэффциентов

            for(int j=0;j<p;j++){

                  cout << mn << "[" << i << "][" << j << "] = ";

                  cin >> k[i][j];// ввести ij-й коэффициент

            }

      }

      cout << endl;

}

// вычисление определителя матрицы

double smatrix::determiner(){

      double t;

      if(p==1) return k[0][0];// матрица 1-го порядка

      else if(p==2){// второго порядка

            t=k[0][0]*k[1][1]-k[0][1]*k[1][0];

            return t;

      }

      else if(p==3){// третьего порядка

            t=((k[0][0])*(k[1][1])*(k[2][2])+(k[0][1])*(k[1][2])*(k[2][0])+(k[0][2])*(k[1][0])*(k[2][1])-

                    ((k[0][2])*(k[1][1])*(k[2][0])+(k[0][0])*(k[1][2])*(k[2][1])+(k[2][2])*(k[0][1])*(k[1][0])));

            return t;

      }

      else return 0.;// если больше - вернуть 0

}

// транспонирование матрицы

void smatrix::transpose(){

      double t;

      // проход элементов матрицы выше главной диагонали

      for(int i=0;i<p;i++){

            for(int j=i+1;j<p;j++){

                  t=k[i][j];  // обменять ij-ый элемент с ji-ым

                  k[i][j]=k[j][i];

                  k[j][i]=t;

            }

      }

}

// вывод матрицы

void smatrix::show(char *mn,ostream& os){

      os << endl << mn << "[" << p << "][" << p << "]=" << endl;// вывести имя матрицы

      for(int i=0;i<p;i++){// пройти все строки

            os << "| ";

            os.precision(3);// задать точность вещественных чисел (кол-во точек после запятой)

            for(int j=0;j<p;j++) os << setw(5) << k[i][j] << " ";// вывести j-й столбец i-й строки

            os << "|" << endl;// завершить вывод строки

      }

      os << endl;

}

// сложение с другой матрицей

void smatrix::sum(const smatrix &m){

      if(p!=m.p) return;// если порядки не совпадают - выйти

      for(int i=0;i<p;i++){// пройти все коэффициенты

            for(int j=0;j<p;j++) k[i][j]+=m.k[i][j];// и сложить соответствующие

      }

}

// смена знака матрицы

void smatrix::neg(){

      for(int i=0;i<p;i++){// пройти весь массив коэффциентов

            for(int j=0;j<p;j++){

                  k[i][j]*=-1;// умножить ij-й коэффициент на -1

            }

      }

}

// ============================================

void smatrix::binread(fstream& ff){// чтение из двоичного файла

      int pp;

      ff.read((char*)&pp,sizeof(pp));// считать порядок матрицы

      if(pp<=0) return;// если она неверная - выйти

      if(k!=NULL) delete []k;// если матрица уже существует - удалить ее

      k=new double*[p];// создать массив строк коэффициентов

      for(int i=0;i<p;i++){

            k[i]=new double[p];// создать i-ю строку

            for(int j=0;j<p;j++){// считать ее коэффициенты

                  ff.read((char*)&k[i][j],sizeof(k[i][j]));

            }

      }

}

void smatrix::binwrite(fstream& ff){// запись в двоичный файл

      ff.write((char*)&p,sizeof(p));// записать порядок матрицы

      for(int i=0;i<p;i++){// и все ее коэффициенты

            for(int j=0;j<p;j++){

                  ff.write((char*)&k[i][j],sizeof(k[i][j]));

            }

      }

}

smatrix smatrix::operator + (const smatrix& m){// сложение

      smatrix tmp(*this);// создать копию текущего объекта

      tmp.sum(m);// добавить к ней второй

      return tmp;// вернуть копию

}

smatrix smatrix::operator - (const smatrix& m){// вычитание

      smatrix tmp(*this);// создать копию текущего объекта

      smatrix t(m);// и переданного

      t.neg();// сменить знак у копии переданного объекта

      tmp.sum(t);// сложить копии

      return tmp;// вернуть результат

}

smatrix& smatrix::operator = (const smatrix& m){// присванивание

      if(this==&m) return *this;// если объект присваивается самому себе - выйти

      p=m.p;// скопировать порядок матрицы

      if(k!=NULL) delete []k;// если матрица уже существует - удалить

      k=new double*[p];// создать массив строк коэффициентов

      for(int i=0;i<p;i++){// скопировать коэффициенты из переданного объекта

            k[i]=new double[p];

            for(int j=0;j<p;j++) k[i][j]=m.k[i][j];

      }

}

smatrix smatrix::operator ++(int){// постфиксный инкремент

      smatrix tmp(*this);// создать копию текущего объекта

      smatrix t(this->p,1);// создать матрицу со всеми коэффициентами равными единице

      sum(t);// добавить к текущему объекту эту матрицу

      return tmp;// вернуть копию (не увеличенную матрицу)

}

smatrix& smatrix::operator ++(){// префиксный инкремент

      smatrix t(this->p,1);// создать матрицу со всеми коэффициентами равными единице

      sum(t);// добавить к текущему объекту эту матрицу

      return *this;// вернуть текущий объект

}

smatrix::operator int(){// преобразование в int

      return determiner();// вернуть определитель матрицы

}

fstream& operator << (fstream& fs,smatrix& m){// вывод в текстовый файловый поток

      fs << m.p << " ";// записать порядок матрицы

      for(int i=0;i<m.p;i++){// и все ее коэффициенты

            for(int j=0;j<m.p;j++){

                  fs << m.k[i][j] << " ";

            }

      }

      return fs;// вернуть переданный поток

}

ostream& operator << (ostream& os,smatrix m){// вывод в текстовый поток

      m.show("",os);// вывести, используя метод объекта

      return os;

}

istream& operator >> (istream& is,smatrix& m){// ввод с текстового потока

      int pp;

      cout << "Rank of matrix: ";

      is >> pp;// ввести размерность

      if(pp<=0){

            cout << "Bad rank" << endl;

            return is;// если она неверная - выйти

      }

      m.p=pp;

      if(m.k!=NULL) delete []m.k;// если матрица существует - выйти

      m.k=new double*[m.p];// создать массив строк коэффициентов

      for(int i=0;i<m.p;i++){

            m.k[i]=new double[m.p];// создать i-ю строку

            for(int j=0;j<m.p;j++){

                  cout << "[" << i << "][" << j << "] = ";

                  is >> m.k[i][j];// считать ij-й коэффициент

            }

      }

      return is;

}

fstream& operator >> (fstream& is,smatrix& m){// ввод с текстового файла

      // отличается от предыдущей функции только тем, что отсутствет вывод сообщений в cout

      int pp;

      is >> pp;// ввести размерность

      if(pp<=0) return is;// если она неверная - выйти

      m.p=pp;

      if(m.k!=NULL) delete []m.k;// если матрица существует - выйти

      m.k=new double*[m.p];// создать массив строк коэффициентов

      for(int i=0;i<m.p;i++){

            m.k[i]=new double[m.p];// создать i-ю строку

            for(int j=0;j<m.p;j++){

                  is >> m.k[i][j];// считать ij-й коэффициент

            }

      }

      return is;

}