Форум программистов, компьютерный форум CyberForum.ru

Переопределение operator [][] - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 10, средняя оценка - 4.60
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 06:54     Переопределение operator [][] #1
Пишу свой класс матрица. Необходимо получать доступ к элементу матрицы.

Пробую переопределить оператор [][] обычным образом, но не получается.
Есть ли еще возможность получить доступ к элементу матрицы через [][]?

написал функцию double Element(int i,int j) {return Matr[i][j];}, но она меня не устраивает....
как быть?
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.12.2011, 06:54     Переопределение operator [][]
Посмотрите здесь:

C++ переопределение
Operator>> C++
operator char() или operator int() C++
переопределение operator[] C++
C++ Expected init-declarator before "operator".expected `,' or `;' before "operator"
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Bers
Заблокирован
19.12.2011, 09:10     Переопределение operator [][] #2
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
struct Test
{
 
    Test(): myMatrix(10, std::vector<int>(10,5) ) {} //заполним пятёрками 
    
   //вернёт строку таблицы
    std::vector<int>& operator[](uint y) { return myMatrix[y]; } 
    
    std::vector< std::vector<int>  > myMatrix;
};
 
 
int main()
{
    Test matrix;
 
    uint x=3,y=2;
    int a= matrix[y][x]; //здесь сначала возвращается строка
                         //и тут же у строки берётся элемент
 
   //можно даже записать так:
  a= (matrix[y]) [x];
 
   //или даже так:
 
  std::vector<int>& line = matrix[y];
  a= line[x];
 
 
}
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 11:27  [ТС]     Переопределение operator [][] #3
как то замудренно немного...

а если я в классе матрицу определяю так:
C++
1
double **Matr;
Как тогда переопределить?

Добавлено через 13 минут
ок, я это исправил. работает. тогда еще вопрос, можно ли в полученную ячейку записать значение? как это сделать?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
19.12.2011, 11:40     Переопределение operator [][] #4
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Пробую переопределить оператор [][]
А такой разве есть?

Добавлено через 1 минуту
Цитата Сообщение от Fantom.AS Посмотреть сообщение
double **Matr;
Это указатель на массив указателей на массивы. Первый индекс индексирует массив даблов, второй - элемент матрицы.
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 11:49  [ТС]     Переопределение operator [][] #5
с этим я уже разобрался.
меня сейчас интересует, можно ли подобным образом записать значение в ячейку?
Bers
Заблокирован
19.12.2011, 11:53     Переопределение operator [][] #6
Цитата Сообщение от Fantom.AS Посмотреть сообщение
как то замудренно немного...
а если я в классе матрицу определяю так:
Какие мы привередливые...
Как принцесса!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
typedef unsigned int uint;
struct Test
{
    uint x,y; //размеры матрицы
    int** myMatrix; //это сама матрица
    
    Test()  //инициализация дин. матрицы
    {
        x=10; y=10; //стартовые размеры матрицы
        myMatrix = new int*[y]; //создали строки матрицы
        
        for( uint iy= 0; iy< y; ++iy)
        {
            myMatrix[iy]= new int[x]; //создали элементы строки матрицы
            
            for (uint ix=0; ix<x; ++ix) 
            {
                myMatrix[iy][ix]=5; //заполнили матрицу пятёрками
            }
        }
    }
    
    ~Test()
    {
        for( uint iy= 0; iy< y; ++iy)
        {
             delete[] myMatrix[iy]; //удалим элементы строки
        }
        delete [] myMatrix; //удалим саму матрицу
    }
 
    //вернёт строку из матрицы
    int* operator[] (uint val) { return myMatrix[val]; } 
};
 
 
int main()
{
    Test matrix;
 
    uint x=3, y=4;
    
    int* line = matrix[y]; //вернёт строку из матрицы
    int val = matrix[y][x]; //вернёт элемент
 
    matrix[y][x]=1; //записали в матрицу
}
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 12:08  [ТС]     Переопределение operator [][] #7
Bers, Я это уже изменил. дописал сам, все работает!
Меня сейчас интересует другое, можно ли подобным образом записать значение в ячейку?
Bers
Заблокирован
19.12.2011, 12:12     Переопределение operator [][] #8
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Bers, Я это уже изменил. дописал сам, все работает!
Меня сейчас интересует другое, можно ли подобным образом записать значение в ячейку?
Вот это для кого было написано:
Цитата Сообщение от Bers Посмотреть сообщение
matrix[y][x]=1; //записали в матрицу
Смотри внимательнее)
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 17:06  [ТС]     Переопределение operator [][] #9
Цитата Сообщение от Bers Посмотреть сообщение
Вот это для кого было написано:
Сообщение от Bers
matrix[y][x]=1; //записали в матрицу
Смотри внимательнее)
Не работает. Я это сразу попробовал. Значение элемента матрицы не меняется...
Bers
Заблокирован
19.12.2011, 17:23     Переопределение operator [][] #10
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Не работает. Я это сразу попробовал. Значение элемента матрицы не меняется...
А... я забыл просто про одну особенность))
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
typedef unsigned int uint;
struct Test
{
    uint x,y; //размеры матрицы
    int** myMatrix; //это сама матрица
 
    Test()  //инициализация дин. матрицы
    {
        x=10; y=10; //стартовые размеры матрицы
        myMatrix = new int*[y]; //создали строки матрицы
 
        for( uint iy= 0; iy< y; ++iy)
        {
            myMatrix[iy]= new int[x]; //создали элементы строки матрицы
 
            for (uint ix=0; ix<x; ++ix) 
            {
                myMatrix[iy][ix]=5; //заполнили матрицу пятёрками
            }
        }
    }
 
    ~Test()
    {
        for( uint iy= 0; iy< y; ++iy)
        {
            delete[] myMatrix[iy]; //удалим элементы строки
        }
        delete [] myMatrix; //удалим саму матрицу
    }
 
    //вернёт строку из матрицы
    int*& operator[] (uint val) { return myMatrix[val]; } 
};
 
 
int main()
{
    Test matrix;
 
    uint x=3, y=4;
    matrix[y][x]=1; //записали в матрицу
 
    int* line = matrix[y]; //вернёт строку из матрицы
    int val = matrix[y][x]; //вернёт элемент
}
Гм?)

Добавлено через 7 минут
хотя.. вот щас проверил по человечески... у меня лично все прекрасно и старый вариант записывал
sandye51
программист С++
 Аватар для sandye51
677 / 579 / 39
Регистрация: 19.12.2010
Сообщений: 2,016
19.12.2011, 17:28     Переопределение operator [][] #11
Цитата Сообщение от Bers Посмотреть сообщение
А... я забыл просто про одну особенность))
не забыл, она тут вообще ни к чему

в этом случае я могу присвоить какой-либо строке левый адрес и при вызове деструктора у тебя все упадет
Bers
Заблокирован
19.12.2011, 17:33     Переопределение operator [][] #12
Цитата Сообщение от sandye51 Посмотреть сообщение
потому что в этом случае я могу присвоить какой-либо строке левый адрес и при вызове деструктора у тебя все упадет
Конечно упадёт.
В любом случае, если ты возвращаешь указатель на внутренние данные своего класса, ты уже нарушаешь инвариант класса. И при желании, его можно будит легко сломать.
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 17:35  [ТС]     Переопределение operator [][] #13
вот мне и интересно, как можно добиться тех же результатов, но не допуская возможности нарушения данных класса
Bers
Заблокирован
19.12.2011, 17:43     Переопределение operator [][] #14
Цитата Сообщение от Fantom.AS Посмотреть сообщение
вот мне и интересно, как можно добиться тех же результатов, но не допуская возможности нарушения данных класса
Данные класса итак не будут нарушены, если не пытаться вредить специально.

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

Подобного рода защита ведёт к падению производительности, и частично усложняет понимание архитектуры продукта.
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.12.2011, 18:34     Переопределение operator [][] #15
Цитата Сообщение от Fantom.AS Посмотреть сообщение
вот мне и интересно, как можно добиться тех же результатов, но не допуская возможности нарушения данных класса
используй (int i, int j), и никого не мучай
Fantom.AS
 Аватар для Fantom.AS
2 / 1 / 0
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 18:35  [ТС]     Переопределение operator [][] #16
хех... я от этого как раз и уйти пытаюсь...
Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.12.2011, 18:37     Переопределение operator [][] #17
Цитата Сообщение от Fantom.AS Посмотреть сообщение
хех... я от этого как раз и уйти пытаюсь...
по другому ни как
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
19.12.2011, 19:29     Переопределение operator [][] #18
Цитата Сообщение от Jupiter Посмотреть сообщение
по другому ни как
Если нельзя, но очень хочется - значит можно!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
#include <iostream>
#include <cassert>
    
class Matrix {
    class Row {
        int * arr;
        int siz;
        Row(const Row & another);
        Row& operator = (const Row & another);
    public:
        Row(int size) : siz(size) {
            arr = new int [ siz ];
        }
        int& operator [] (int pos) {
            assert( pos > -1 && pos < siz );
            return arr[pos];
        }
        ~Row() {
            delete [] arr;
        }
    };
    Row ** matr;
    int rows;
    int columns;
 
    Matrix(const Matrix & another);
    Matrix& operator = (const Matrix & another);
    
public:
    Matrix(int r, int c) : rows(r), columns(c) {
        assert( rows > 0 && columns > 0 );
        
        matr = new Row* [ rows ];
        for ( int i = 0; i < rows; ++i )
            matr[i] = new Row(columns);
    }
    Row & operator [] (int pos) {
        assert( pos > -1 && pos < rows);
        
        return *(matr[pos]);
    }
    ~Matrix() {
        for ( int i = 0; i < rows; ++i )
            delete matr[i];
        delete [] matr;
    }
};
 
 
int main(){
    Matrix m(2, 2);
    m[0][0] = 13;
    m[1][1] = 69;
    
    std::cout << m[0][0] << " " << m[1][1] << std::endl;
    
    return 0;
}
На самом деле так, конечно, лучше не делать (вернее этого мало, всё должно быть чуть сложнее). Честно говоря, сам не верил, что отработает...
Код
andrew@rd-andrew ~/cpp/classes
$ g++ -o simple_matrix simple_matrix.cpp

andrew@rd-andrew ~/cpp/classes
$ ./simple_matrix
13 69

Не по теме:

Цитата Сообщение от Bers Посмотреть сообщение
будит легко
Легко не будет! Снова карточки давать за безграмотность?

Jupiter
Каратель
Эксперт C++
6542 / 3962 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
19.12.2011, 19:32     Переопределение operator [][] #19
easybudda, не вижу принципиального отличия от
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
19.12.2011, 19:49     Переопределение operator [][]
Еще ссылки по теме:

C++ Operator=
Operator = C++
Реализация operator + через operator += C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
easybudda
Модератор
Эксперт С++
 Аватар для easybudda
9372 / 5422 / 914
Регистрация: 25.07.2009
Сообщений: 10,423
19.12.2011, 19:49     Переопределение operator [][] #20
Цитата Сообщение от Jupiter Посмотреть сообщение
не вижу принципиального отличия
А попробуйте всю строку оптом заменить - не выйдет. У меня Row - закрытый класс. Вызывать его методы получится, а вот мутить что-то с переменными этого типа не так просто...
Yandex
Объявления
19.12.2011, 19:49     Переопределение operator [][]
Ответ Создать тему
Опции темы

Текущее время: 11:42. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru