Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.91/11: Рейтинг темы: голосов - 11, средняя оценка - 4.91
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
1

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

19.12.2011, 06:54. Показов 2026. Ответов 20
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Пишу свой класс матрица. Необходимо получать доступ к элементу матрицы.

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

написал функцию double Element(int i,int j) {return Matr[i][j];}, но она меня не устраивает....
как быть?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
19.12.2011, 06:54
Ответы с готовыми решениями:

переопределение operator[]
я унаследовался вот так: template <class TKey, class TData> class fixedSizeCache: public...

Глобальное переопределение "operator <<" для char *
Здравствуйте. Привожу пример для демонстрации проблемы. Помогите пожалуйста в ее устранении или...

Class & operator's |Error: undefined reference to operator
Компилирует нормально, но когда хочу использовать оператор выдает ошибку:undefined reference to...

Вызов operator[] через operator[] const
Перелистывал Майерса, наткнулся на код, подскажите пожалуйста почему он советует закомментированный...

20
Заблокирован
19.12.2011, 09:10 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];
 
 
}
1
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 11:27  [ТС] 3
как то замудренно немного...

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

Добавлено через 13 минут
ок, я это исправил. работает. тогда еще вопрос, можно ли в полученную ячейку записать значение? как это сделать?
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
19.12.2011, 11:40 4
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Пробую переопределить оператор [][]
А такой разве есть?

Добавлено через 1 минуту
Цитата Сообщение от Fantom.AS Посмотреть сообщение
double **Matr;
Это указатель на массив указателей на массивы. Первый индекс индексирует массив даблов, второй - элемент матрицы.
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 11:49  [ТС] 5
с этим я уже разобрался.
меня сейчас интересует, можно ли подобным образом записать значение в ячейку?
0
Заблокирован
19.12.2011, 11:53 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; //записали в матрицу
}
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 12:08  [ТС] 7
Bers, Я это уже изменил. дописал сам, все работает!
Меня сейчас интересует другое, можно ли подобным образом записать значение в ячейку?
0
Заблокирован
19.12.2011, 12:12 8
Цитата Сообщение от Fantom.AS Посмотреть сообщение
Bers, Я это уже изменил. дописал сам, все работает!
Меня сейчас интересует другое, можно ли подобным образом записать значение в ячейку?
Вот это для кого было написано:
Цитата Сообщение от Bers Посмотреть сообщение
matrix[y][x]=1; //записали в матрицу
Смотри внимательнее)
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 17:06  [ТС] 9
Цитата Сообщение от Bers Посмотреть сообщение
Вот это для кого было написано:
Сообщение от Bers
matrix[y][x]=1; //записали в матрицу
Смотри внимательнее)
Не работает. Я это сразу попробовал. Значение элемента матрицы не меняется...
0
Заблокирован
19.12.2011, 17:23 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 минут
хотя.. вот щас проверил по человечески... у меня лично все прекрасно и старый вариант записывал
0
программист С++
860 / 600 / 147
Регистрация: 19.12.2010
Сообщений: 2,014
19.12.2011, 17:28 11
Цитата Сообщение от Bers Посмотреть сообщение
А... я забыл просто про одну особенность))
не забыл, она тут вообще ни к чему

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

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

Подобного рода защита ведёт к падению производительности, и частично усложняет понимание архитектуры продукта.
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 18:34 15
Цитата Сообщение от Fantom.AS Посмотреть сообщение
вот мне и интересно, как можно добиться тех же результатов, но не допуская возможности нарушения данных класса
используй (int i, int j), и никого не мучай
0
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 18:35  [ТС] 16
хех... я от этого как раз и уйти пытаюсь...
0
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 18:37 17
Цитата Сообщение от Fantom.AS Посмотреть сообщение
хех... я от этого как раз и уйти пытаюсь...
по другому ни как
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
19.12.2011, 19:29 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 Посмотреть сообщение
будит легко
Легко не будет! Снова карточки давать за безграмотность?

1
Каратель
Эксперт С++
6609 / 4028 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 19:32 19
easybudda, не вижу принципиального отличия от
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
12458 / 7482 / 1753
Регистрация: 25.07.2009
Сообщений: 13,762
19.12.2011, 19:49 20
Цитата Сообщение от Jupiter Посмотреть сообщение
не вижу принципиального отличия
А попробуйте всю строку оптом заменить - не выйдет. У меня Row - закрытый класс. Вызывать его методы получится, а вот мутить что-то с переменными этого типа не так просто...
2
19.12.2011, 19:49
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.12.2011, 19:49
Помогаю со студенческими работами здесь

operator char() или operator int()
Здорова госпдо! Снова ничо не ясно как всегда. Разбираю программку из книги Страуструпа, там он...

Перегрузка operator>> и operator<< в абстрактном классе
Здрасьте! Есть необходимость перегрузить потоки, Я знаю как это сделать через friend, но вот...

Реализация operator + через operator +=
внутри следующей темы возник вопрос, ответ на который так и не был получен:...

Перегрузить операторы operator+() и operator*() в пользовательском классе "Комплексное число"
Здравствуйте. Предлагаю заняться арифметикой. Создал прослейший класс, перегрузил операторы...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru