Привет!
Решил написать код, который бы смотрел как меняются указатели на буфер при чтении и записи в различных потоковых классах, в часности в filebuf (basic_filebuf):
#include #include #include using namespace std; class inspectorfile:public fstream{ public: inspectorfile(const char*file):fstream(file){} void print(){ cout<<"put buffer: "; cout<<(const void*)(rdbuf()->pbase())<<' '<<(const void*)(rdbuf()->pptr())<<' '<<(const void*)(rdbuf()->epptr())<<" : "<<*((const char*)(rdbuf()->pptr()))<<endl; cout<<"get buffer: "; cout<<(const void*)(rdbuf()->eback())<<' '<<(const void*)(rdbuf()->gptr())<<' '<<(const void*)(rdbuf()->egptr())<<endl; cout<<endl; } }; int main(){ int i=0; char c='?'; inspectorfile fs("file"); fs.print(); fs<<"hello"; fs.print(); fs.seekg(1);cout<<"seek"<<endl; fs.print(); fs>>c; cout<<"read character: "<<c<<endl; fs.print(); return 0; }
Объявляю класс от fstream’а.
В нём метод rdbuf() возвращает указатель на буфер, который использует fstream.
Далее, существуют методы, которые возвращают указатели на начало, конец и текущую позицию read/write буфера и того их шесть:
pbase
pptr
epptr
eback
gptr
egptr
Но проблема в том, что эти методы protected. Для того что бы их вызвать я решил сделать inspectorfile дружественный для filebuf.
В OpenBSD (gcc 3.3.5) всё проходит успешно.
В Linux Slackware 12 (gcc 4.1.2) выводятся ошибки:
/usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf: In member function 'void inspectorfile::print()': /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:516: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::pbase() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:29: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:519: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::pptr() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:29: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:522: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::epptr() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:29: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:519: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::pptr() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:29: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:469: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::eback() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:31: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:472: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::gptr() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:31: error: within this context /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:475: error: '_CharT* std::basic_streambuf<_CharT, _Traits>::egptr() const [with _CharT = char, _Traits = std::char_traits]' is protected filestream.cc:31: error: within this context filestream.cc: In function 'int main()': filestream.cc:39: error: reference to 'inspectorfile' is ambiguous filestream.cc:23: error: candidates are: class inspectorfile /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:123: error: struct std::inspectorfile filestream.cc:39: error: reference to 'inspectorfile' is ambiguous filestream.cc:23: error: candidates are: class inspectorfile /usr/lib/gcc/i486-slackware-linux/4.1.2/../../../../include/c++/4.1.2/streambuf:123: error: struct std::inspectorfile filestream.cc:39: error: expected `;' before 'fs' filestream.cc:41: error: 'fs' was not declared in this scope
friend class inspectorfile; объявил в классе basic_filebuf
ругается компилятор почему-то на basic_streambuf, на всякий случай я объявил и там, но ошибка не исчезла.
Подскажите, пожалуйста, в чём проблема.
Последние комментарии
- OlegL, 17 декабря в 15:00 → Перекличка 21
- REDkiy, 8 июня 2023 года в 9:09 → Как «замокать» файл для юниттеста в Python? 2
- fhunter, 29 ноября 2022 года в 2:09 → Проблема с NO_PUBKEY: как получить GPG-ключ и добавить его в базу apt? 6
- Иванн, 9 апреля 2022 года в 8:31 → Ассоциация РАСПО провела первое учредительное собрание 1
- Kiri11.ADV1, 7 марта 2021 года в 12:01 → Логи catalina.out в TomCat 9 в формате JSON 1
Компилятор ругается не случайно. Если basic_streambuf имеет protected-члены, то компилятор гарантирует, что никто кроме потомков и друзей их не будет использовать. Для того, чтобы стать другом basic_filebuf, надо влезть в сорцы libstdc++ и сделать из неё libNONstdc++.
Если очень хочется именно так, я бы попытался сделать такое:
С точки зрения ООП — это гадость: мы насильно повышаем тип от basic_filebuf до my_filebuf, причём не по теме повышаем. Но доступ у нас, появляется.
Зачем лезть в сырцы, когда доступ задаётся в заголовках?
Хорошо, я залез в сырцы, и что мне там менять?
Я думаю, стоит изменить заголовки и пересобрать libstdc++. Стоит заглянуть в сырцы, и подогнать их под заголовки. Не знаю. Я с c++ сталкиваюсь лишь эпизодически, при этом изо всех сил стараясь этих столкновений избегать.
Я думаю вряд ли потому как спецификации доступа для этапа компиляции существуют. На код они не влияют, наверно… Во всяком случае на новый класс, на новый код.
Какие нибудь идеи есть?
Скомпилироваться должно, если в заголовках правильно поправил. Точно не хватает ; после конструктора. Как-то править заголовки libstdc++ у меня нет желания.
Всяко это не так, так как за проверку синтаксиса отвечает компилятор, а не линковщик. И ему нет дела какой есть бинарный код…