使用C ++运算符重载,可以创建一个模拟指针类型的类,因此我正在尝试使用这种方法抽象FILE
读取操作。
class FilePointer
{
FILE* file;
size_t position;
FilePointer (FILE* file, size_t position)
{
this->file = file;
this->position = position;
};
public:
FilePointer (FILE* file)
{
this->file = file;
this->position = 0;
};
FilePointer operator+ (size_t offset)
{
return FilePointer(file,position + offset);
};
FilePointer operator++ () // Prefix : ++FilePointer
{
position++;
return *this;
};
FilePointer operator++ (int) // Postfix : FilePointer++
{
FilePointer before = *this;
position++;
return before;
};
FilePointer operator+= (size_t offset)
{
position += offset;
return *this;
};
uint8_t operator* ()
{
fseek(file,position,SEEK_SET);
Uint8 out;
fread(&out,1,1,file);
return out;
};
uint8_t operator[] (size_t offset)
{
return *(*this + offset);
};
};
从上面的代码片段中可以看出,我能够找出如何区分增量运算符的变体,从而使给定的FilePointer f;
f++
和++f
表现得很直观。
但是,如果我想将此类用于文件 writes ,该怎么办?目前,我可以抓取一个字节uint8_t something = f[0];
并且它可以工作,但是如果我要“设置”某些东西,即f[0] = 100;
,那么按原样进行的重载将不起作用。
除了这是否是“良好实践”(尽管也可以随意考虑)之外,还有没有办法在类的运算符重载中实现此行为?
uint8_t n = f[0];
n++;
f[0] = n;
或者,变得更加幻想,像这样:
f[1]++;
我想可以做到的一种方法是实现另一个表示“已取消引用的FilePointer”的类,但是很好奇是否可以仅使用FilePointer类本身的重载。
答案 0 :(得分:2)
我想可以做到的一种方法是实现另一个表示“已取消引用的FilePointer”的类
那几乎是唯一的方法。它将是“代理类型”的对象,可以将其转换为uint8_t
(在这种情况下可能是隐式的,尽管通常我不喜欢隐式转换),但是也可以将其分配给它。
必须使用FilePointer*
构造它,并且必须是friend
,以便它可以调用适当的“写入”功能。
但是,这会有点儿麻烦,因为它可能很快变得“悬而未决”,并在错误的位置书写。您还可以在构造代理对象时存储当前位置,并在编写时查找到必要的位置 iff 。但是,所有寻求并不是很有效。
也一次读取一个字节很容易。
总的来说,尽管您的尝试令人钦佩,但我还是建议您不要采用这种方法。如果范围超出范围,您至少可以将FILE*
包装在一个不错的类中,该类可以为您完成fclose
。
但是很好奇,是否有可能仅使用FilePointer类本身的重载。
我不这么认为。从operator[]
返回的任何内容都需要某种魔术状态,该状态可以接受“设置”值并连接到FILE*
机械。返回uint8_t
绝对是不允许您这样做的。
答案 1 :(得分:0)
另一种提高1个字符写入性能的方法可能是,您的代理文件指针实际上是一个缓冲区,该缓冲区以某种方式收集了许多分配,然后将它们全部销毁到文件中。
使用代理方法要注意的一件事是,调用者可以使用auto
或auto&
保留许多代理对象,并尝试无序更新它们。我认为没有解决此问题的有效方法。
另外,operator --
又如何呢?尽管c ++库确实具有单向迭代器的概念。也许迭代器是更好的隐喻?