[C++] как написать operator[]
const CPoint point; point[0];
вызовет второй оператор
на double v=point[0] вызывался const double& operator[](unsigned int index) const,
а на point[0]=5 вызывался double& operator[](unsigned int index)?
Насколько я знаю, никак.
double v=point[(int)0]
point[(unsigned int)0]=5
Правда я не уверен, что это сработает. В шарпе сработало бы точно.
Тогда зачем вообще операторы ? Сделать 2 метода типа double read(int) и write(int, double).
только никак не могу вспомнить, как именно....
помню, что делал вспомогательный класс, который на самом деле использовался в одном из вариантов..
и потом никакик дополнительных телодвижений (типа явных приведений) делать не надо было....
#include <stdio.h>
class io_byte {
private:
FILE *const f;
unsigned long pos;
public:
io_byte(FILE *f1, unsigned long pos1): f(f1 pos(pos1) {}
operator char const {fseek(f,pos,SEEK_SET); return fgetc(f);}
const io_byte &operator=(char c) const {fseek(f,pos,SEEK_SET); fputc(c,f); return *this;}
};
class file_vector {
private:
FILE *f;
public:
file_vector(const char *fname) {f= fopen(fname,"r+");}
~file_vector {fclose(f);}
io_byte operator[](unsigned long i) {return io_byte(f,i);}
};
int main
{
file_vector f("aaa");
char c=f[3]='A';
printf("%c%c\n",cchar)f[4]);
return 0;
}
А по возвращаемому значению функции не специализируются (AFAIK) .
ну вот и решение проблемы топика :о)
Хотя для каких-то случаев оно применимо.
Нормальное решение... Особенно если учесть что тут все будет инлайниться. Никакого оверхеда по сравнению с просто fseek fgetc. Хотя я бы например сделал mmap и не парился.
Чего страшного-то, снаружи ведь конфетка, а что внутри - пофиг. И совершенно справедливо, что overhead-а нет.
gcc -O2 -fomit-frame-pointer -funroll-loops -finline-functions
Что еще стоит включить ?
Ты это остро почувствуешь тогда, когда места на диске под создание файла не останется или диск будет попросту закрыт на запись. В чем же дело, спросит тогда конечный пользователь. Почему оператор индекса не работает? Ебта?
Исключение вылетит.
Да, и вправду конечному пользователю будет очень удивительно, откуда прилетает ИО ексепшен про то что диск фулл, если он использует буфер мапящийся на файл! "В чем же дело?" - спросит он себя, - "почему же не работает мой ненаглядный оператор индекса?"
класс был написан только из спортивного интереса.
такой стиль программирования на С++ (когда происходит разврат в пользу "красоты" кода) я не считаю удачным.
насчёт эксэпшенов... вы не поверите, что произойдёт если запустить программу, на создав ей предварительно файл "aaa".
А какой смысл сравнивать fgetc с обычным char[] ? Надо сравнивать C-ную программу, использующую fgetc и C++-ную программу, в которой fgetc спрятан под operator []
Компилировал gcc с опцией -S, действительно компилятор вставляет туда много всякой фигни... Не знаю, существует ли компилятор, который скомпилит это дело нормально, и вообще, возможен ли он. Но я никаких препятствий не вижу пока.
class Char
{
char & chr;
public:
Char(char & chr)
: chr(chr) {}
void operator = (char chr)
{
this->chr = chr;
}
operator char
{
return(chr);
}
};
class CharArray
{
char * data;
public:
CharArray(int size)
: data(new char[size])
{}
~CharArray
{
delete[] data;
}
Char operator [](int index)
{
return(Char(data[index];
}
};
int __declspec(noinline) test(int size)
{
00401000 push esi
CharArray a(size);
00401001 mov esi,dword ptr [esp+8]
00401005 push edi
00401006 push esi
00401007 call operator new[] (401BE8h)
0040100C add esp,4
for(int i=0; i<size; i++)
0040100F xor ecx,ecx
00401011 test esi,esi
00401013 jle test+1Dh (40101Dh)
a[i] = i;
00401015 mov byte ptr [ecx+eax],cl
00401018 inc ecx
00401019 cmp ecx,esi
0040101B jl test+15h (401015h)
int s = 0;
0040101D xor edi,edi
for(int i=0; i<size; i++)
0040101F xor ecx,ecx
00401021 test esi,esi
00401023 jle test+30h (401030h)
s+= a[i];
00401025 movsx edx,byte ptr [ecx+eax]
00401029 add edi,edx
0040102B inc ecx
0040102C cmp ecx,esi
0040102E jl test+25h (401025h)
return(s);
00401030 push eax
00401031 call operator delete[] (401C12h)
00401036 add esp,4
00401039 mov eax,edi
0040103B pop edi
0040103C pop esi
}
0040103D ret
Куда уж лучше то?
Оставить комментарий
Sanjaz
Почему вызывается 2 раза double& operator[](unsigned int index)?
Что здесь не правильно?