Не соображу что не так при перегрузке оператора =...
От: Vulko http://kvolkov.com
Дата: 17.05.05 18:13
Оценка:
Заранее прошу не тереть модеров тему. Хоть и я пишу всё на C++, но в данном случае разницы нету никакой. На дельфи всё почти также.

Есть класс динамической матрицы. Пишу перегрузку оператора =, чтобы можно было легко присваивать матрицы.

В итоге присвоения не происходит. Хоть убей, не пойму что не так в алгоритме присваивания...


 class Array2D
  {
    double **base;
    int columnSize;
    int rowSize;
   public:
    Array2D(int arrayColumnSize, int arrayRowSize); //Êîíñòðóêòîð
    ~Array2D(); //Äåñòðóêòîð
    void push(int, int, double psh); // Ââîä
    double pop(int i, int j); // Âûâîä
    void GetSize(int &n, int &m); // Âûâîä ðàçìåðîâ ìàòðèöû
    Array2D &operator=(Array2D &arr);
  };

// Êîíñòðóêòîð îáúåêòîâ êëàññà
  Array2D::Array2D(int arrayColumnSize, int arrayRowSize)
   {
    base = new double*[arrayColumnSize];
     for ( int i = 0; i < arrayColumnSize; ++i )
      base[i] = new double[arrayRowSize];
    rowSize = arrayRowSize;
    columnSize = arrayColumnSize;
     for ( int i = 0; i < columnSize; ++i )
      for ( int j = 0; j < rowSize; ++j )
       base[i][j] = 0;
   }

// Äåñòðóêòîð îáúåêòîâ êëàññà
  Array2D::~Array2D()
   {
    for ( int i = 0; i < columnSize; ++i )
     delete[] base[i];
    delete[] base;
   }

// Ââîä [i, j]-òîãî ýëåìåíòà ìàññèâà
  void Array2D::push(int i, int j, double psh)
   {
    base[i][j] = psh;
   }

// Âûâîä [i, j]-òîãî ýëåìåíòà ìàññèâà
  double Array2D::pop(int i, int j)
   {
    return base[i][j];
   }

// Âûâîä ðàçìåðîâ ìàòðèöû
  void Array2D::GetSize(int &n, int &m)
   {
    n = columnSize;
    m = rowSize;;
   }

// присваивание
  Array2D &Array2D::operator=(Array2D &arr)
   {
    int i, j, k, l;
    this -> GetSize(i, j);
    arr.GetSize(k, l);
    if (i != k)
     if (j != l)
      for (i = 0; i < k; i++)
       for (j = 0; j < l; j++)
        this -> push( i, j, arr.pop(i, j) );
    return *this;
   }
Re: Не соображу что не так при перегрузке оператора =...
От: jazzer Россия Skype: enerjazzer
Дата: 17.05.05 20:14
Оценка:
Здравствуйте, Vulko, Вы писали:

вот так и должно быть?
    if (i != k)
     if (j != l)

или все же тут равенство?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Не соображу что не так при перегрузке оператора =...
От: vdimas Россия  
Дата: 18.05.05 06:55
Оценка:
Здравствуйте, Vulko, Вы писали:

V>Заранее прошу не тереть модеров тему. Хоть и я пишу всё на C++, но в данном случае разницы нету никакой. На дельфи всё почти также.


V>Есть класс динамической матрицы. Пишу перегрузку оператора =, чтобы можно было легко присваивать матрицы.


V>В итоге присвоения не происходит. Хоть убей, не пойму что не так в алгоритме присваивания...


1. if (i == k && j == l)
2. а где else?
Re: Не соображу что не так при перегрузке оператора =...
От: Кирпа В.А. Украина  
Дата: 18.05.05 07:20
Оценка:
Здравствуйте, Vulko, Вы писали:

V
V>// присваивание
V> Array2D &Array2D::operator=(Array2D &arr)
V> {
V> int i, j, k, l;
V> this -> GetSize(i, j);
V> arr.GetSize(k, l);
V> if (i != k)
V> if (j != l)
V> for (i = 0; i < k; i++)
V> for (j = 0; j < l; j++)
V> this -> push( i, j, arr.pop(i, j) );
V> return *this;
V> }
V>[/code]

Со своей колокольни позволю добавить что оператор присвоения должен иметь
немного другую сигнатуру


Array2D &Array2D::operator=(const Array2D &arr)
!0xDEAD
Re[2]: Не соображу что не так при перегрузке оператора =...
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.05 09:23
Оценка: +1
Здравствуйте, Кирпа В.А., Вы писали:

КВА>Со своей колокольни позволю добавить что оператор присвоения должен иметь

КВА>немного другую сигнатуру


КВА>
КВА>Array2D &Array2D::operator=(const Array2D &arr)
КВА>


разве что с колокольни, потому что по стандарту — не должен (как и конструктор копирования, кстати)
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re[3]: Не соображу что не так при перегрузке оператора =...
От: Кирпа В.А. Украина  
Дата: 18.05.05 10:43
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Кирпа В.А., Вы писали:


КВА>>Со своей колокольни позволю добавить что оператор присвоения должен иметь

КВА>>немного другую сигнатуру


КВА>>
КВА>>Array2D &Array2D::operator=(const Array2D &arr)
КВА>>


J>разве что с колокольни, потому что по стандарту — не должен (как и конструктор копирования, кстати)


Согласен что не должен но const в операторе присвоения это правило хорошего тона ИМХО
(как никак дополнительно развязывает руки оптимизатору компилятора)
Да и согласись что если в операции копмрования изменяется объект то это не совсем gut
Так хоть компилятор на такие действия рявкнет при банальной описке а иначе ищи трудно уловимый баг
!0xDEAD
Re[4]: Не соображу что не так при перегрузке оператора =...
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.05 10:50
Оценка:
Здравствуйте, Кирпа В.А., Вы писали:

КВА>Согласен что не должен но const в операторе присвоения это правило хорошего тона ИМХО

КВА>(как никак дополнительно развязывает руки оптимизатору компилятора)
КВА>Да и согласись что если в операции копмрования изменяется объект то это не совсем gut
КВА>Так хоть компилятор на такие действия рявкнет при банальной описке а иначе ищи трудно уловимый баг

в большинстве случаев — да, хотя есть и обратные примеры, например, std::auto_ptr
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
Re: Не соображу что не так при перегрузке оператора =...
От: Bars99  
Дата: 18.05.05 11:57
Оценка:
V>
 
V>// присваивание
V>  Array2D &Array2D::operator=(Array2D &arr)
V>   {
V>    int i, j, k, l;
V>    this -> GetSize(i, j);
V>    arr.GetSize(k, l);
V>    if (i != k)
V>     if (j != l)
V>      for (i = 0; i < k; i++)
V>       for (j = 0; j < l; j++)
V>        this -> push( i, j, arr.pop(i, j) );
V>    return *this;
V>   }
V>


Что мне не понравилось в Вашем операторе присваивания:
1) Размеры двух массивов могут не совпадать, в этом случае, у this нужно удалить base и выделить память заново под новый размер, а также изменить значения columnSize и rowSize
2) Копировать содержимое объекта arr в текущий массив нужно всегда, а не только когда размеры массивов не совпадали.

Теперь ответ на Ваш вопрос "почему оператор не работает". Он работает, только если хотябы один размер массивов совпадает, то он ничего не делает (см. пункт 2). Если размеры не совпадают, то делает, но неправильно (может выходить за рамки выделенной памяти, см. пункт 1).
Re[5]: Не соображу что не так при перегрузке оператора =...
От: Кирпа В.А. Украина  
Дата: 18.05.05 12:02
Оценка:
Здравствуйте, jazzer, Вы писали:

J>Здравствуйте, Кирпа В.А., Вы писали:


КВА>>Согласен что не должен но const в операторе присвоения это правило хорошего тона ИМХО

КВА>>(как никак дополнительно развязывает руки оптимизатору компилятора)
КВА>>Да и согласись что если в операции копмрования изменяется объект то это не совсем gut
КВА>>Так хоть компилятор на такие действия рявкнет при банальной описке а иначе ищи трудно уловимый баг

J>в большинстве случаев — да, хотя есть и обратные примеры, например, std::auto_ptr


Ну std::auto_ptr это отдельная песня
то что они открыли оператор присвоения и конструктор копирования сами себе навредили
тем самым получив проблемы хранения их в контейнерах

Вот BOOST уже таких глупостей избежал


template<class T> class scoped_ptr // noncopyable
{
private:

    T * ptr;

    scoped_ptr(scoped_ptr const &);
    scoped_ptr & operator=(scoped_ptr const &);

public:
...
};
!0xDEAD
Re[6]: Не соображу что не так при перегрузке оператора =...
От: jazzer Россия Skype: enerjazzer
Дата: 18.05.05 12:40
Оценка:
Здравствуйте, Кирпа В.А., Вы писали:

J>>в большинстве случаев — да, хотя есть и обратные примеры, например, std::auto_ptr


КВА>Ну std::auto_ptr это отдельная песня

КВА>то что они открыли оператор присвоения и конструктор копирования сами себе навредили
КВА>тем самым получив проблемы хранения их в контейнерах

КВА>Вот BOOST уже таких глупостей избежал


будет с моей стороны большой наглостью сказать, что boost::scoped_ptr и std::auto_ptr решают разные задачи?
jazzer (Skype: enerjazzer) Ночная тема для RSDN
Автор: jazzer
Дата: 26.11.09

You will always get what you always got
  If you always do  what you always did
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.