Мне нужно перегрузить операторы [] и '=' для класса, который содержит файл для записи в позицию в файле. Например, этот код должен работать:
UserFileClass File;
printf("%c",File[53]); //printing character from the 53 position in the file
File[34]='d'; //34th character in the file will be rewriten with d
Но как это сделать, если после перегрузки [] для возврата char мы не можем перезаписать что-либо в объекте с помощью оператора '='. Я пытался сделать это по-другому, но он тоже не работает:
#include <iostream>
#include <fstream>
using namespace std;
class File
{
fstream file;
char buffer;
int charPos;
public:
File(string fileName);
~File(){file.close();};
File & operator[](int position);
File & operator=(const char &);
friend ostream & operator<<(ostream,File);
};
File::File(string fileName)
{
file.open(fileName);
if(!file)
{
cerr<<"File reading error";
exit(1);
}
}
ostream & operator<<(ostream outStream, File obj)
{
outStream<<obj.buffer;
return outStream;
}
File & File::operator[](int position)
{
file.seekg(position);
if(file.eof())
{
buffer='\0';
}
else
{
file.read(&buffer,1);
charPos=position;
}
return *this;
}
File & File::operator=(const char & charValue)
{
file.seekg(charPos);
file.write(&charValue,1);
return *this;
}
void main()
{
File userFile("file.txt");
cout<<userFile[2];
userFile[4]='a';
}
Ошибка компиляции: ошибка 2 ошибки C2248: std :: basic_ios <_Elem, _Traits> :: basic_ios: не может получить доступ к частному члену...
Обычным решением было бы для operator[]
вернуть прокси-сервер по строкам:
class UserFile
{
//...
char get( int index ) const { ... }
void set( int index, char newValue ) { ... }
class Proxy
{
UserFile* myOwner;
int myIndex;
public:
Proxy( UserFile* owner, int index )
: myOwner( owner )
, myIndex( index )
{
}
Proxy const& operator=( char ch ) const
{
myOwner->set( myIndex, ch ):
return *this;
}
operator char() const
{
return myOwner->get( myIndex );
}
};
Proxy operator[]( int index )
{
return Proxy( this, index );
}
};
Конечно, это не сработает при сопоставлении ...
в вызове функции, поэтому вы не можете использовать его напрямую с printf
. (Но тогда действительно нет оправданий для использования printf
в C++. Или любая другая функция, которая имеет varargs.) Вам нужно было бы явно передать ее char
:
printf( "%c", static_cast<char>( file[42] ) );
seekg
и read
. И это не потребовало бы броска.
[]
. Как еще вы бы сделали это без прокси. (И так как это C ++, тот факт , что он не работает без проблем с printf
не является проблемой, она работает с std::ostream
.)
ostream & operator<<(ostream outStream, File obj)
Это выражение неверно. Должен быть:
ostream& operator<<(ostream& outStream, File obj)
^^^^^^^^ .................... Note the &
Кроме того, я не вижу необходимости в этом классе вообще. Кажется, это оболочка вокруг fstream
, но ничего не делает, что fstream
не делает, и должен использовать ее для загрузки.
Замечание: если этот класс определен в файле заголовка, вы не хотите размещать using namespace std;
в файле заголовка!
std::ostream
не копируется.printf
это C, а не C ++.