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

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

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

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

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

написал функцию double Element(int i,int j) {return Matr[i][j];}, но она меня не устраивает....
как быть?
0
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
19.12.2011, 06:54
Ответы с готовыми решениями:

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

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

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

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

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

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

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

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

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

Подобного рода защита ведёт к падению производительности, и частично усложняет понимание архитектуры продукта.
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 18:34
Цитата Сообщение от Fantom.AS Посмотреть сообщение
вот мне и интересно, как можно добиться тех же результатов, но не допуская возможности нарушения данных класса
используй (int i, int j), и никого не мучай
0
 Аватар для Fantom.AS
2 / 1 / 2
Регистрация: 17.11.2010
Сообщений: 121
19.12.2011, 18:35  [ТС]
хех... я от этого как раз и уйти пытаюсь...
0
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 18:37
Цитата Сообщение от Fantom.AS Посмотреть сообщение
хех... я от этого как раз и уйти пытаюсь...
по другому ни как
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
19.12.2011, 19:29
Цитата Сообщение от 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;
}
На самом деле так, конечно, лучше не делать (вернее этого мало, всё должно быть чуть сложнее). Честно говоря, сам не верил, что отработает...
Code
1
2
3
4
5
6
andrew@rd-andrew ~/cpp/classes
$ g++ -o simple_matrix simple_matrix.cpp
 
andrew@rd-andrew ~/cpp/classes
$ ./simple_matrix
13 69

Не по теме:

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

1
Каратель
Эксперт С++
6610 / 4029 / 401
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
19.12.2011, 19:32
easybudda, не вижу принципиального отличия от
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,973
19.12.2011, 19:49
Цитата Сообщение от Jupiter Посмотреть сообщение
не вижу принципиального отличия
А попробуйте всю строку оптом заменить - не выйдет. У меня Row - закрытый класс. Вызывать его методы получится, а вот мутить что-то с переменными этого типа не так просто...
2
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
19.12.2011, 19:49
Помогаю со студенческими работами здесь

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

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

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

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

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


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Первый деплой
lagorue 16.01.2026
Не спеша развернул своё 1ое приложение в kubernetes. А дальше мне интересно создать 1фронтэнд приложения и 2 бэкэнд приложения развернуть 2 деплоя в кубере получится 2 сервиса и что-бы они. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит: токи, напряжения и их 1 и 2 производные при t = 0;. . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Изучаю kubernetes
lagorue 13.01.2026
А пригодятся-ли мне знания kubernetes в России?
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru