Перегрузка двух квадратных скоб - PullRequest
11 голосов
/ 12 апреля 2011

Я пишу матричный класс на c ++ и пытаюсь перегрузить некоторые операторы, такие как = и >> и << и т. Д. </p>

Мне не удалось перегрузить оператор [] [] для класса матрицы. если у меня есть объект матрицы классов, такой как M1, тогда я могу использовать этот способ для присвоения значения каждому элементу:

M1[1][2]=5;

OR

int X;

X=M1[4][5];

Ответы [ 8 ]

19 голосов
/ 12 апреля 2011

Просто перегрузите operator[] и заставьте его вернуть указатель на соответствующую строку или столбец матрицы.Поскольку указатели поддерживают подписку с помощью [], доступ с помощью нотации «двойной квадрат» [][] возможен.

Вы также можете перегрузить operator() двумя аргументами.

9 голосов
/ 12 апреля 2011

В C ++ нет operator[][].Вы должны return вспомогательный объект и затем перегрузить operator[] для этого, чтобы иметь такой доступ.

3 голосов
/ 12 апреля 2011

Вы можете перегрузить operator[].Поэтому, если вы хотите использовать матрицу таким образом, вы должны сделать матрицу массивом векторов.

class Matrix
{
...
  Vector & operator[]( int index );
...
};

и

class Vector
{
...
  double & operator[]( int index );
...
};

Наконец:

Matrix m;
...
double value = m[i][j];
...
3 голосов
/ 12 апреля 2011

нет operator[][], вы можете реализовать operator[] для возврата ссылки на объект строки / столбца, в котором вы можете реализовать operator[] для возврата вам ссылки на ячейку.

Выможет сделать что-то вроде следующего, чтобы избежать всех этих хлопот ..

struct loc
{
  int x;
  int y;
};

, затем в вашей перегрузке operator[] примите loc, что-то вроде

T& operator[](loc const& cLoc)
{
 // now you have x/y you can return the object there.
}

Для вызоваВы можете просто сделать что-то вроде:

matrix[loc(2,3)] = 5; 
2 голосов
/ 07 июня 2014

На самом деле, я сделал это в своем собственном классе матрицы несколько лет назад.В этом случае я определил класс шаблона матрицы, который содержал фрагмент ниже.

Затем я смог выполнить итерацию и назначить следующее:

          for(size_t k=1; k<n; ++k) {       
                   minor[p][k-1]=major[j][k];        
           }

Надеюсь, это поможет.

// //////////////////////////////////////////////////////////////////////////////
// list is internal vector representation of n x m matrix
T* list;
// Proxy object used to provide the column operator
template < typename T >
class OperatorBracketHelper
{
    Matrix < T > & parent ;
    size_t firstIndex ;

    public :
        OperatorBracketHelper ( Matrix < T > & Parent , size_t FirstIndex ) : 
        parent ( Parent ), firstIndex ( FirstIndex ) {}

        // method called for column operator
        T & operator []( size_t SecondIndex )
        {
            // Call the parent GetElement method which will actually retrieve the element
            return parent.GetElement ( firstIndex , SecondIndex );
        }
};

// method called for row operator
OperatorBracketHelper < T > operator []( size_t FirstIndex )
{
    // Return a proxy object that "knows" to which container it has to ask the element
    // and which is the first index (specified in this call)
    return OperatorBracketHelper < T >(* this , FirstIndex );
}

T & GetElement ( size_t FirstIndex , size_t SecondIndex )
{
    return list[FirstIndex*cols+SecondIndex];
}
1 голос
/ 22 сентября 2017

Я точно работаю над классом матрицы, и я решил сначала создать класс Array, который имеет динамический двумерный массив.Итак, как и вы, я столкнулся с этим препятствием: я могу перегрузить две квадратные скобки.Как я подошел к этому делу очень просто;Я перегружал оператор квадратных скобок дважды как функции-члены.Сначала я перегрузил [], чтобы вернуть, так сказать, указатель, указывающий на нужную строку, а затем следующая функция-член (то есть снова перегруженный оператор []) возвращает значение l того же типа, что и элементы массива.*

Однако обратите внимание, что индекс, который вы вызываете для вызова предыдущего перегруженного оператора [], должен быть где-то сохранен, чтобы вы могли использовать его в последнем перегруженном операторе [].По этой причине я просто добавил новый член типа int в класс Array (который я назвал «test» в моем коде ниже).

class Array {

private: 

 double **ptr; int test;
 ...   /* the rest of the members includes the number of rows and columns */

public:
    Array(int=3,int=3);  // Constructor
    Array(Array &);      // Copy Constructor
    ~Array();            // Destructor
    void get_array();
    void show_array();
    double* operator[] (int);
    double operator[] (short int);
    ...
};

... 

double* Array::operator[] (int a) {
    test = a;
    double* p = ptr[test];
    return p;
}

double Array::operator[] (short int b) {
   return ((*this)[test][b]);
}

Для этого, например, в mainЯ могу просто написать:

int main(){
Array example;
cout << example[1][2];  
}

Надеюсь, это поможет вам.

0 голосов
/ 05 октября 2018

Шаблон матрицы класса

template <uint8_t rows, uint8_t cols, typename T>
class MatrixMxN {
public:
    T* operator[](uint8_t f_row) {
        return &m_val[f_row * cols];
    }
protected:
    T m_val[rows*cols];
};

а вот объект матрицы с 3 строками, 4 столбцами и целочисленным типом.

MatrixMxN<3, 4, int32_t> M;
M[2][3] = 10;
std::cout << M[2][3] << std::endl;
0 голосов
/ 12 апреля 2011

Вы не можете перегрузить [][] как таковой, поскольку такого оператор. Вы можете перегрузить [], чтобы вернуть то, что также имеет [], определенный на нем (прокси); в простейшем случае, что-то вроде double* будет работать, но обычно лучше, хотя немного больше работы, чтобы использовать полный класс. (Место для добавления проверка границ, например.)

В качестве альтернативы вы можете перегрузить (x,y). В зависимости от того, кто ты спросите, один формат или другой "лучше". (На самом деле это строго вопрос стиля.)

...