如何重载运算符以在 operator[] 调用上调用 setter 函数?

SF.*_*SF. 5 c++ operator-overloading getter-setter

如何重载类的运算符,以便使用的语法

classInstance[index] = value;
Run Code Online (Sandbox Code Playgroud)

施行

classInstance.cfgfile.Write(index,value)
Run Code Online (Sandbox Code Playgroud)

背景资料;随意跳过。

我们开发的应用程序使用内存映射访问一段 NVRAM——实际上,映射的只是两个寄存器,地址和数据。您写入地址寄存器,然后写入或读取数据寄存器。初始化后,读取和写入由一个简单的 [] 重载类执行,该类持有对内存段的引用。您引用实例的 [] 给出要读取和写入的单元格的命名空间索引,然后它会做它的事情。

int& IndirectMemory::operator[](RTCMemIndex idx)
{
    *midx_reg = idx;
    return *mdata_reg;
}
Run Code Online (Sandbox Code Playgroud)

(代码去除了互斥和健全性检查等不相关元素)。

一切正常……只要 NVRAM 工作正常。这种特定的芯片已经停产,而那些“野外”的芯片目前已经开始衰老。它们的功能对我们的使用来说意义不大,如果芯片损坏,我们可以将它们的角色转移到闪存上,几乎没有影响(只是闪存磨损多一点)。事情是我们想使用我们的配置格式使用闪存记录,它使用 getter 和 setter。

int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);
Run Code Online (Sandbox Code Playgroud)

在代码的许多地方,我们通过编写IndirectMemory[Some_Register] = Some_Value;经常更改的各种内容来调用 NVRAM ,并且我们希望在重启后保持不变。我想保留这种语法和行为,但如果检测到 NVRAM 已损坏或通过配置条目手动禁用,则能够写入文件。


网络上充斥着使用 operator[] 来设置给定值的示例,只需返回对它的引用即可。对于例如

unsigned long operator [](int i) const    {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}
Run Code Online (Sandbox Code Playgroud)

在如果我叫这种情况下,也就是说,reg[3] = 1;[]将一个参考返回元素#3,默认operator=将写入参考就好了。

但是由于我无法返回对文件中键的引用(.WriteKey()只是执行完整的写入,返回成功或错误),并且operator=不带索引,所以我担心这个简单的选项无济于事。

Nat*_*ica 4

可以使用代理类来解决这个问题。由于value无法传递,classInstance我们需要创建一个operator[]可以返回的对象,该对象将获取其值value并知道将操作应用于哪个实例。使用

struct Proxy
{
    classInstance_type& to_apply;
    index_type index;
    Proxy(classInstance_type& to_apply, index_type index) : to_apply(to_apply), index(index) {}
    Proxy& operator=(value_type const & value)
    {
        to_apply.cfgfile.Write(index,value)
        return *this;
    }
};
Run Code Online (Sandbox Code Playgroud)

你的班级operator[]看起来像

Proxy operator[](index_type index)
{
    return Proxy{*this, index};
}
Run Code Online (Sandbox Code Playgroud)

然后,当您classInstance[index] = value;调用Proxy's时operator=,它会引用要调用的对象、要使用的索引以及您还需要的值。