переопределение [][]
От: black_claster Россия  
Дата: 29.10.10 07:46
Оценка:
Здравствуйте.
Вот делаю класс по сути дела аналог динамического массива.
при инициализации одномерного массива и выборки из него элементов проблем не возникло:

clas DM
{
public:
DM();
~DM();
char& operator[] (int position);
char *POINT;
char **POINT_2;
void init(int number);
void init2(int i,intj);
}
DM::DM()
{
memset(this,0,sizeof(DM));
}
DM::~DM()
{
delete POINT;
}

void DM::init(int number)
{
POINT=new char[number];
}
void DM::init2(int i,int j)
{
POINT2=new char[i];
for(int n=0;n<i;n++)
{
POINT2[n]=new char[j];
}
}
char& operator[] (int position)
{
if(position<=MAX_SIZE)return POINT[position];

}



и в программе соответственно можно записать так:

DM NP;
NP.init(9);
NP[0]='t';


А вот как сделать так чтобы можно было оперировать в двумерном случае,
т.е.
DM NP;
NP.init(5,5);

NP[1][2]='n';

я не знаю.

Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.

Заранее благодарен.
Re: переопределение [][]
От: placement_new  
Дата: 29.10.10 07:49
Оценка:
Здравствуйте, black_claster, Вы писали:

_>Здравствуйте.

_>Вот делаю класс по сути дела аналог динамического массива.
_>при инициализации одномерного массива и выборки из него элементов проблем не возникло:

_>clas DM

_>{
_> public:
_> DM();
_> ~DM();
_> char& operator[] (int position);
_> char *POINT;
_> char **POINT_2;
_> void init(int number);
_> void init2(int i,intj);
_>}
_>DM::DM()
_>{
_> memset(this,0,sizeof(DM));
_>}
_>DM::~DM()
_>{
_> delete POINT;
_>}

_>void DM::init(int number)

_>{
_> POINT=new char[number];
_>}
_>void DM::init2(int i,int j)
_>{
_> POINT2=new char[i];
_> for(int n=0;n<i;n++)
_> {
_> POINT2[n]=new char[j];
_> }
_>}
_>char& operator[] (int position)
_>{
_> if(position<=MAX_SIZE)return POINT[position];

_>}




_>и в программе соответственно можно записать так:


_>DM NP;

_>NP.init(9);
_>NP[0]='t';


_>А вот как сделать так чтобы можно было оперировать в двумерном случае,

_>т.е.
_>DM NP;
_>NP.init(5,5);

_>NP[1][2]='n';


_>я не знаю.


_>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


_>Заранее благодарен.


Или делать прокси, в которой тоже определен [], или довольствоваться GetAt(int x, int y);
Re: переопределение [][]
От: artem_korneev США https://www.linkedin.com/in/artemkorneev/
Дата: 29.10.10 07:50
Оценка:
Здравствуйте, black_claster, Вы писали:

_>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


Первый operator[] должен возвращать прокси-класс, второй operator[] будет обращаться уже к объекту прокси-класса.
С уважением, Artem Korneev.
Re: переопределение [][]
От: Ytz https://github.com/mtrempoltsev
Дата: 29.10.10 07:51
Оценка: +1
Здравствуйте, black_claster, Вы писали:

_>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


_>Заранее благодарен.


Тебе надо использовать прокси-класс. Можешь прочесть об этом в правиле 30 книги Мэерса 35 правил программирования на С++.
Re: переопределение [][]
От: Vain Россия google.ru
Дата: 29.10.10 08:00
Оценка:
Здравствуйте, black_claster, Вы писали:

_>Здравствуйте.

_>Вот делаю класс по сути дела аналог динамического массива.
_>при инициализации одномерного массива и выборки из него элементов проблем не возникло:
_>...
_>А вот как сделать так чтобы можно было оперировать в двумерном случае,
Зачем?

_>т.е.

_>DM NP;
_>NP.init(5,5);
_>NP[1][2]='n';
_>я не знаю.
_>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.
Двойного или двумерного?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re[2]: переопределение [][]
От: K13 http://akvis.com
Дата: 29.10.10 08:46
Оценка: 24 (3)
_>Или делать прокси, в которой тоже определен [], или довольствоваться GetAt(int x, int y);

Совершенно необязательно. Если элементы в памяти лежат построчно, то подойдет обычный operator[](int row) возвращающий указатель на элемент в начале строки
Только адресация будет не [x][y] а как и в обычном Си [row][col]

Вторая [] обработается автоматически — как с обычным указателем. Но если нужен контроль выхода за границу -- то только через прокси.
Re[2]: переопределение [][]
От: black_claster Россия  
Дата: 29.10.10 09:19
Оценка:
Здравствуйте, Ytz, Вы писали:

Ytz>Здравствуйте, black_claster, Вы писали:


_>>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


_>>Заранее благодарен.


Ytz>Тебе надо использовать прокси-класс. Можешь прочесть об этом в правиле 30 книги Мэерса 35 правил программирования на С++.


А каков механизм взятия числа из вторых скобок?
Можете пожалуйста кинуть ссылочку с примером?
Re[2]: переопределение [][]
От: black_claster Россия  
Дата: 29.10.10 09:27
Оценка:
Здравствуйте, Vain, Вы писали:

V>Здравствуйте, black_claster, Вы писали:


_>>Здравствуйте.

_>>Вот делаю класс по сути дела аналог динамического массива.
_>>при инициализации одномерного массива и выборки из него элементов проблем не возникло:
_>>...
_>>А вот как сделать так чтобы можно было оперировать в двумерном случае,
V>Зачем?

_>>т.е.

_>>DM NP;
_>>NP.init(5,5);
_>>NP[1][2]='n';
_>>я не знаю.
_>>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.
V>Двойного или двумерного?

двумерного.
И вот еще не ясно как быть-класс предпологает использование как одномерного так и двумерного массива,
а переопределение оператора [] должно быть одно на оба случая?
Re[3]: переопределение [][]
От: Erop Россия  
Дата: 29.10.10 09:44
Оценка: +3
Здравствуйте, black_claster, Вы писали:

_>И вот еще не ясно как быть-класс предпологает использование как одномерного так и двумерного массива,

_>а переопределение оператора [] должно быть одно на оба случая?

Моэно сделать специализацию. Но, вообще-то, мне лично больше нравится использование круглых скобок.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: переопределение [][]
От: Ytz https://github.com/mtrempoltsev
Дата: 29.10.10 09:48
Оценка:
Здравствуйте, black_claster, Вы писали:

_>Здравствуйте, Ytz, Вы писали:


Ytz>>Здравствуйте, black_claster, Вы писали:


_>>>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


_>>>Заранее благодарен.


Ytz>>Тебе надо использовать прокси-класс. Можешь прочесть об этом в правиле 30 книги Мэерса 35 правил программирования на С++.


_>А каков механизм взятия числа из вторых скобок?

_>Можете пожалуйста кинуть ссылочку с примером?

Книгу я тебе подсказал, возьми да прочитай, там как раз это рассматривается.
Re[3]: переопределение [][]
От: Vain Россия google.ru
Дата: 29.10.10 09:57
Оценка:
Здравствуйте, black_claster, Вы писали:

_>>>Здравствуйте.

_>>>Вот делаю класс по сути дела аналог динамического массива.
_>>>при инициализации одномерного массива и выборки из него элементов проблем не возникло:
_>>>...
_>>>А вот как сделать так чтобы можно было оперировать в двумерном случае,
V>>Зачем?
_>>>т.е.
_>>>DM NP;
_>>>NP.init(5,5);
_>>>NP[1][2]='n';
_>>>я не знаю.
_>>>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.
V>>Двойного или двумерного?
_>двумерного.
_>И вот еще не ясно как быть-класс предпологает использование как одномерного так и двумерного массива,
_>а переопределение оператора [] должно быть одно на оба случая?
Вопрос, зачем это нужно вообще, когда можно просто перевести все размерности в одну?
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Re: переопределение [][]
От: Roman Odaisky Украина  
Дата: 29.10.10 10:19
Оценка: +4
Здравствуйте, black_claster, Вы писали:

_>Подскажите пожалуйста как переопределить оператор выборки для случая двойного массива.


Определи operator () с двумя аргументами и не страдай. Причем в некотором смысле это правильнее, чем [] — ведь любой массивоподобный объект есть по сути отображение множества индексов на множество значений, так что пользоваться им как функцией вполне логично.
До последнего не верил в пирамиду Лебедева.
Re: переопределение [][]
От: MasterZiv СССР  
Дата: 29.10.10 12:12
Оценка:
On 29.10.2010 11:46, black_claster wrote:
> Подскажите пожалуйста как переопределить оператор выборки для случая двойного
> массива.

Последовательно. Сначала одни скобки переопределяем, потом в классе,ссылку
на тип которого возвращают первые скобки, переопределяем вторые скобки.
Posted via RSDN NNTP Server 2.1 beta
Re[3]: переопределение [][]
От: Chorkov Россия  
Дата: 29.10.10 15:06
Оценка: -1
Здравствуйте, black_claster, Вы писали:
_>А каков механизм взятия числа из вторых скобок?
_>Можете пожалуйста кинуть ссылочку с примером?

template<class CHolder, class CReturn, class CIndex >
class proxy
{
  CHolder& ref;
  CIndex index;
public:
  proxy(CHolder& ref, CIndex index) : ref(ref), index(index) {}
  CReturn& operator[] (CIndex index2) const { return ref.at(index, index2); }
};

class Matrix
{
public:
    double& at(int i, int j);
    const double& at(int i, int j) const;

    proxy<Matrinx, double, int> operator[] (int i) { return proxy<Matrinx, double, int>(*this, i); }
    proxy<const Matrinx, const double, int> operator[] (int i) const { return proxy<const Matrinx, const double, int>(*this, i); }
};
Re: переопределение [][]
От: peterbes Россия  
Дата: 31.10.10 04:36
Оценка:
Здравствуйте, black_claster, Вы писали:

Довольно интересный синтаксис реализован в blitz++, там все так предопределено, что синтаксис программ больше напоминает синтаксис матлаба
Re[2]: переопределение [][]
От: peterbes Россия  
Дата: 31.10.10 04:46
Оценка:
вдогонку. Может быть вы изобретаете свой велосипед, посмотрите в сторону valarry, ваша задача может быть реализована на простом одномерном динамическом массиве, а реализация "многомерности" осуществляется через внутреннее индексирование этого массива
Re[4]: переопределение [][]
От: peterbes Россия  
Дата: 31.10.10 04:48
Оценка: +1
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, black_claster, Вы писали:


_>>И вот еще не ясно как быть-класс предпологает использование как одномерного так и двумерного массива,

_>>а переопределение оператора [] должно быть одно на оба случая?

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


Мне скобки тоже больше нравятся
Re: переопределение [][]
От: Lexey Россия  
Дата: 31.10.10 08:45
Оценка:
Здравствуйте, black_claster, Вы писали:

_>Вот делаю класс по сути дела аналог динамического массива.


Про то, как надо, уже много написали. Добавлю немного про то, как не надо. :D

_>DM::DM()
_>{
_> memset(this,0,sizeof(DM));
_>}


За такое молотком по рукам бить нужно. Если завтра у класса появится база или автоматически конструируемые члены, то будет очень весело.

_>DM::~DM()
_>{
_> delete POINT;
_>}


И за такое тоже. Массив нужно удалять через delete[], а не через скалярный delete.
И кто POINT2 будет удалять?

И вообще, все это сильно смахивает на изобретение очередного велосипеда с квадратными колесами.
Re[2]: переопределение [][]
От: sizeof_void Россия  
Дата: 12.11.10 18:52
Оценка:
Здравствуйте, Lexey, Вы писали:

L>Здравствуйте, black_claster, Вы писали:


_>>Вот делаю класс по сути дела аналог динамического массива.


L>Про то, как надо, уже много написали. Добавлю немного про то, как не надо. :D


L>
_>>DM::DM()
_>>{
_>> memset(this,0,sizeof(DM));
_>>}
L>


L>За такое молотком по рукам бить нужно. Если завтра у класса появится база или автоматически конструируемые члены, то будет очень весело.


L>
_>>DM::~DM()
_>>{
_>> delete POINT;
_>>}
L>


L>И за такое тоже. Массив нужно удалять через delete[], а не через скалярный delete.

L>И кто POINT2 будет удалять?

L>И вообще, все это сильно смахивает на изобретение очередного велосипеда с квадратными колесами.



Добавлю в догонку, что вот эта функция:

void DM::init2(int i,int j)
{
POINT2=new char[i]; 
for(int n=0;n<i;n++)
{
POINT2[n]=new char[j];
}
}


... делает следующее: сперва аллоцирует массив из i char (1 байт),
а затем присваивает каждому из них указатель char* (4 байта в 32-бит. системе)
на создаваемые массивы, из-за чего реальные адреса их теряются и память "утекает". =)
Надо исправить на " POINT2=new char*[i]; ".

А тут:
char& operator[] (int position)
{
if(position<=MAX_SIZE)return POINT[position];

}


... надо сравнивать не с константой MAX_SIZE, а с реальным количеством выделенных в функции init() элементов. И return по умолчанию добавить (без него не скомпилится), а лучше else с генерацией исключения. %)
"May the Force be with us all!" (c)
Re[3]: переопределение [][]
От: ST1 Россия  
Дата: 12.11.10 19:33
Оценка:
Пример построчного хранения двумерного массива в std::vector
#define RS2D(i,j,ny) ((i) * (ny) + (j))

/**
 * Dynamic 0-based row-oriented 2D array (storage is only one std::vector)
 */
template<class T>
class array2d : public std::vector<T> {
public:
    typedef std::vector<T> baseClass;
    typedef int index;

    array2d(index nx = 0, index ny = 0) {
        Resize(nx, ny);
    }

    void Resize(index nx, index ny) {
        baseClass::resize(nx * ny);
        nx_ = nx;
        ny_ = ny;
    }

    void Resize(index /*lr*/, index ur, index /*lc*/, index uc) {
        Resize(ur + 1, uc + 1);
    }

    void Clear() {
        baseClass::clear();
        nx_ = 0;
        ny_ = 0;
    }

    const T &At(index i, index j) const {
        return at(RS2D(i, j, ny_));
    }

    virtual T &At(index i, index j) {
        return at(RS2D(i, j, ny_));
    }

    const T &operator()(index i, index j) const {
        return At(i, j);
    }

    T &operator()(index i, index j) {
        return At(i, j);
    }

    void FillRow(index irow, T val) {
        DASSERT(CHR(irow, 0, nx_));
        iterator beg = begin() + RS2D(irow, 0, ny_);
        fill(beg, beg + ny_, val);
    }

public:
    index nx_;
    index ny_;
};
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.