Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Для новичков > operator


Автор: Arden 23.6.2009, 09:47
Код

#include <cstdlib>
#include <iostream>

using namespace std;

class matrix{
      public:
             char name;
             int **A,x,y;
             matrix(char n, int a, int b);
             void fill();
             void print();
             void change(int a, int b);
             matrix& operator=(const matrix &other);
             matrix& operator+=(const matrix &other);
             const matrix operator+(const matrix &other);
      };

int main(int argc, char *argv[])
{
    matrix a('A',2,2);
    a.fill();
    cout<<endl;
    matrix b('B',2,2);
    b.fill();
    cout<<endl;
    a + b;
    a.print();
    cout<<endl;
    b.print();
    system("PAUSE");
    return EXIT_SUCCESS;
}

matrix::matrix(char n, int a, int b){ // конструктор
                    name = n; 
                    x = a;
                    y = b;
                    A = new int*[x];            // создает динамический двумерный массив
                    for(int i=0; i<x; i++){
                            A[i] = new int[y];
                            }
                    }
                    
void matrix::fill(){                                 // вбиваем массив вручную
     for(int i=0; i<x; i++){
             for(int j=0; j<y; j++){
                     cout<<name<<"["<<i+1<<"]["<<j+1<<"]=";
                     cin>>A[i][j];
                     }
             }
     }

void matrix::print(){                              // выводим массив на экран
     for(int i=0; i<x; i++){
             for(int j=0; j<y; j++){
                     cout<<A[i][j]<<" ";
                     }
             cout<<endl;
             }
     }
     
void matrix::change(int a, int b){          // метод удаляет массив, и создает новый размера а на b
     for(int i=0; i<x; i++){
             delete[] A[i];
             }
     delete[] A;
     x=a;
     y=b;
     A = new int*[x];
     for(int i=0; i<x; i++){
             A[i] = new int[y];
             }
     }

// дальше пошли дефиниции трёх операторов =, += и +, которые, собственно, 
// меня и интересуют

matrix& matrix::operator=(const matrix &other){
        if(x == other.x && y == other.y){
             for(int i=0; i<x; i++){
                     for(int j=0; j<y; j++){
                             A[i][j]=other.A[i][j];
                             }
                     }
             }
        else{
             change(other.x, other.y);
             for(int i=0; i<x; i++){
                     for(int j=0; j<y; j++){
                             A[i][j]=other.A[i][j];
                             }
                     }
             }
        }
        
matrix& matrix::operator+=(const matrix &other){
        for(int i=0; i<x; i++){
                for(int j=0; j<y; j++){
                        A[i][j]+=other.A[i][j];
                        }
                }
        return *this;
        }
        
const matrix matrix::operator+(const matrix &other){
      matrix result = *this;
      result += other;
      return result;
      }


Почему при использовании операции a + b, значение a изменяется? Ведь по сути оператор + у меня не меняет this, а лишь возвращает объект. Создается копия this, на этой копии используется описанный ранее оператор +=, и эта же копия возвращается в программу:
Код

const matrix matrix::operator+(const matrix &other){
      matrix result = *this;
      result += other;
      return result;
      }


Каким вообще боком тогда изменяется this?

Кстати, если сделать вот так:
Код

matrix a('A',2,2);
    a.fill();
    cout<<endl;
    matrix b('B',2,2);
    b.fill();
    cout<<endl;
    с = a + b;


то а при этом вообще получает рандомные значения. Просветите неуча, пожалуйста. Честно, очень старался сам найти ошибку... неосилил smile Спасибо заранее smile 

Автор: zim22 23.6.2009, 09:54
объявите в классе operator+ как friend.
и копирующий конструктор определите.
тогда сможете написать так:

Код

matrix operator+(const matrix &lhs, const matrix &rhs) {
  matrix ret(lhs);
  ret += rhs;
  return ret;
}

Автор: azesmcar 23.6.2009, 10:03
Arden, 
Цитата(Arden @  23.6.2009,  09:47 Найти цитируемый пост)
matrix result = *this;

Проблема в том, что тут вызывается не оператор присваивания а копирующий конструктор. Вы его не писали - следовательно компилятор сгенерирует его сам. (подробнее см. http://forum.vingrad.ru/forum/topic-262056/anchor-entry1887548/0.html)
У вас там есть указательм, компилятор генерирует копирующий конструктор не зная об этом, следовательно он просто скопирует указатель и у вас будет два обьекта ссылающихся на одну и ту же область памяти.
Код

matrix::matrix(const matrix& r) :name(r.name), x(r.x), y.(r.y)
{
    A = new int*[x];            // создает динамический двумерный массив
    for(int i=0; i<x; i++){
        A[i] = new int[y];
        for (int j = 0; j < y; ++j)
            A[i][j] = r.A[i][j];
    }
}

добавьте вот это (вроде правильно, но стоит проверить, писал тут), должно полегчать smile

Автор: Arden 2.7.2009, 01:32
azesmcar, спасибо большое. 
Вопрос решен.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)