Понимание полезности перегрузки оператора - PullRequest
0 голосов
/ 30 апреля 2018

Я работал над кодом класса "DenseMatrix", целью которого является создание регулярных матриц.

Проходя через код, есть 2 или 3 вещи, которые я не совсем понимаю.
Итак, сначала вот код этого класса:

#include<iostream>
#include<complex>
#include<vector>
#include <cassert>

using namespace std ;

class DenseMatrix{
    typedef complex<double> Cplx;

private:
    int nr, nc;
    vector<Cplx> data;

public :
    DenseMatrix(const int& nr0, const int& nc0){
    nr = nr0; nc = nc0; data.resize(nr*nc,0);}

    DenseMatrix(const DenseMatrix& M){
    nr = M.nr; nc = M.nc; data.resize((M.data).size());
    for (int j=0; j<data.size(); j++) {data[j]=M.data[j];} }

    void operator=(const DenseMatrix& M){
    nr = M.nr ; nc = M.nc ; data.resize((M.data).size());
    for (int j=0; j<data.size() ; j++){data[j]=M.data[j];} }

    Cplx& operator () (const int& j ,const int& k) {
    assert(0<=j && j<nr && 0<=k && k<nc) ; return data[k+j*nc];}

    const Cplx& operator () (const int& j ,const int& k) const {
    assert(0<=j && j<nr && 0<=k && k<nc) ; return data[k+j*nc];}

    friend ostream& operator<<(ostream& o , const DenseMatrix& M){
    for ( int j =0; j<nr ; j++){ for ( int k=0; k<nc; k++){o << M(j,k) << "\ t " ;} o << endl ;}
    //return o ;}
};

Во-первых, какая польза от определения оператора "=", если мы действительно можем использовать конструктор копирования и получить тот же результат?

Во-вторых, если мое понимание верно, Cplx& operator () вернет ссылку, и эта ссылка фактически позволит нам изменить приватный атрибут (элемент matix). Но что делает второе определение оператора const Cplx& operator () (const int& j ,const int& k) const? В чем его полезность?

Спасибо!

Ответы [ 3 ]

0 голосов
/ 30 апреля 2018

Во-первых, какая польза от определения оператора "=", если мы действительно можем использовать конструктор копирования и получить тот же результат?

Это два разных зверя. Конструктор копирования позволяет вам создавать новый объект как копию существующего; оператор присваивания позволяет копировать объект поверх существующего. Итак:

DenseMatrix foo;
...
DenseMatrix bar(foo); // copy constructor
...
foo = bar; // assignment operator

Разница тонкая, но важная: конструктор копирования начинается с нетронутого объекта, тогда как оператор присваивания обычно также должен избавиться от существующих данных.

Тем не менее, учитывая, что оператор присваивания, как правило, очень похож на конструктор деструктор + копирование (при этом большая часть кода дублируется), часто идиома копирования и замены используется для минимизации дублирования кода (при достижении других полезных свойств - таких как сильный). гарантии исключений в процессе).


Но что делает второе определение оператора, const Cplx& operator () (const int& j ,const int& k) const? В чем его полезность?

Перегрузка const - это та, которая вызывается для const экземпляров класса (или для "обычных" экземпляров, доступных через указатель или ссылку const); в этом случае они будут возвращать те же данные, что и не const версия, но в виде ссылки const вместо простой ссылки, что не позволяет вызывающей стороне изменять данные матрицы в соответствии с константой объект, над которым он вызывается.

0 голосов
/ 30 апреля 2018

Во-первых, какая польза от определения оператора "=", если мы действительно можем использовать конструктор копирования и получить тот же результат?

Потому что вы не можете использовать конструктор копирования для получения того же результата. Конструктор копирования является конструктором; он используется, когда вы строите матрицу. Оператор присваивания позволяет назначать уже построенную матрицу.

Во-вторых, если мое понимание верно, Cplx & operator () вернет ссылку, и эта ссылка фактически позволит нам изменить [элемент матрицы].

Но что делает второе определение оператора, const Cplx& operator () (const int& j ,const int& k) const?

Эта версия предназначена для случаев, когда у вас есть const DenseMatrix. Представьте, что вы использовали обычный operator() - вы получите Cplx&, который вы можете использовать для изменения элементов матрицы. Но вы не можете изменять матричные элементы, если это матрица const. Компилятор не позволит использовать первую версию матрицы const.

Последний const (перед {) говорит, что эту функцию можно вызывать на const DenseMatrix.

0 голосов
/ 30 апреля 2018

Ссылки не разрешают доступ к закрытым атрибутам. Это ничем не отличается от работы с самим голым объектом.

Фраза наличия двух версий функции, одна из которых const, а другая нет, встречается довольно часто. Поскольку функция возвращает ссылку, она возвращает ссылку const из функции const.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...