hi!
Мы не поняли друг друга.
Есть класс Buffer, внутри которого переменная private: char *buf;
Есть некоторые 2 функции ввода-вывода, про которых известно только что они возвращают число прочитанных или записанных байт и один из параметров каждой функции - Buffer.
==> Необходимо сделать общие функции Buffer::read/Buffer::write,
которые принимали бы в качестве параметра указатель на функцию чтения, переменную Buffer (в/из которой читать/писать) и собственное переменное число других параметров. Так, как вызов делается внутри Buffer ==> эта функция чтения/записи может работать непосредственно с приватным указателем на char, который определен внутри Buffer.
Проблема кроется вот в чем...
1) как обнаружить среди параметров ф-ции Buffer::read переменную типа class Buffer и подсунуть вместо нее Buffer::buf (пусть этот параметр может быть только один) ?
2) как взять все эти парамтры (c этой замененной переменной) и пихнуть их в вызов функции ввода вывода, указатель на которую передается.
Код должен, по моему разумению, выглядеть примерно так:
class Buffer {
private:
char *buf;
int datalen;
.....
public:
int read( int ( *_reader(...), ...)) {
/* заменяем единственный параметр типа Buffer на Buffer::buf */
/* делаем вызов ф-ции ввода/вывода: */
int breaded = ( *_reader)( /* аргументы, переданные ф-ции Buffer::read с замененным параметром типа Buffer на Buffer::buf */);
this->datalen += breaded;
return( breaded);
}
}
/* где многоточия - переменное число параметров. */
Buffer buff;
buff.read( &recv, sockfd, buff, 1024, options);
^^^^
после чего имеем в буфере добавочку - полученную строку. :)
Как раз мысль для того, чтобы не заниматься ненужными выделениями/копированиями памяти.
А если делать как Вы предложили - функцию, возвращающую указатель на Buffer::buf, то это снимает идею защищенности данных.
По всей видимости, тут необходимо выполнять операции непосредственно со стеком... Но ничего в явном виде не сказано ни в книжках, ни в мануале по stdarg.
Есть мысли?
WBR, Dvorkin
-----------------------------------------------
>>>есть класс Buffer, в котором определена
>>>private переменная buf
>
>Тип buf не указан - считаем
>его char*.
>
>>>class Buffer {
>>>private buf;
>>>....
>>>}
>...
>>>int Buffer::read( int _param, int (
>>>*_reader)(...)) { ...... }
>>>В ф-цию Buffer::read передается указатель на
>>>функцию чтения.
>
>И buf и read являются членами
>класса Buffer.
>
>>>Внутри ф-ции read
>>>мы имеем доступ к закрытым
>
>Ну естественно.
>
>>>переменным класса и каким-то образом
>>>пихаем в ф-цию _reader эту
>>>переменную.
>
>И чем ЭТОТ ПОДХОД отличается от
>принципа друзей ?
>Только тем, что кроме buf'а твой
>reader ничего другого не увидит.
>
>
>>>
>>>Можно ли так?
>
>Почему же нет, только криво это,
>ИМХО( см. ЗЫЖ )
>
>>>Если можно, то как?
>>>
>
>Объяви функцию
>char* Buffer::getBufPrt() { return buf };
>
>например. После чего ты сможешь адрес
>переменной таскать куда хочешь и
>как хочешь. НО: ты сначала
>получишь вне класса указатель на
>его закрытый член, передашь его
>какой-то ф-ции чтения, потом указатель
>на ту функцию чтения будешь
>передавать в другой член класса.
>Бег по кругу.
>
>>>WBR, Dvorkin
>>
>>Да, функция _reader имеет переменное число
>>параметров.
>
>Не понял. Если не знаешь как
>сделать перерменное число параметров, читай
>man stdarg. В других случаях
>- объясни в чем проблема.
>
>
>ЗЫЖ
>Прежде всего я всегда имею класс
>работы с файлами. Делать его
>10 минут, а пользоваться можно
>всегда. Но если идти по
>твоему пути я сделал бы
>так:
>В класссе Buffer:
>Buffer& operator << ( const char*
>str )
>{
> //Контроль размеров данных
>!
> ...
> //
> buf[0] = 0;
>
> strcat( buf, str
>);
> return *this;
>}
>После чего извне класса Buffer можно
>писАть в эту переменную что
>угодно, и как тебе нравится:
>
>...
>Buffer* ptrBuf = new Buffer...;
>const char aaa[] = "Test writing";
>
>...
>ptrBuf << aa;
>...
>При таком подходе ты избавляешься
>от перетаскивания указателей - эти
>операции САМЫЕ опасные в С
>ибо указатели обладают очень неприятными
>свойствами: теряться и портиться -
>,а все чтения из файла
>остаются вне класса и не
>путаются под ногами.