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

时间:2019-01-21 14:59:15

标签: c++ operator-overloading getter-setter

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

的语法
classInstance[index] = value;

执行

classInstance.cfgfile.Write(index,value)

背景信息;随时跳过。

我们开发的应用程序使用内存映射访问一段NVRAM-实际上,映射的只是地址和数据这两个寄存器。您先写入地址寄存器,然后写入或读取数据寄存器。初始化之后,将通过对包含对内存段的引用的类进行简单的[]重载来执行读取和写入操作。您引用实例的[]来提供要读取和写入的单元格的命名空间索引,然后它就完成了它的工作。

int& IndirectMemory::operator[](RTCMemIndex idx)
{
    *midx_reg = idx;
    return *mdata_reg;
}

(去除了互不相关的元素(例如互斥锁和完整性检查)的代码。

一切正常...只要NVRAM正常工作。这种特定的芯片已经停产,而“荒野”的芯片目前已经过时了。它们的功能对我们的使用意义不大,并且如果芯片损坏,我们可以将它们的角色转移到闪存中而几乎没有影响(只是稍微增加了闪存的磨损)。问题是我们想使用我们的配置格式使用Flash记录,该格式使用getter和setter。

int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);

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


网上充斥着使用operator []来设置给定值的示例,仅通过返回给定值即可。对于example

unsigned long operator [](int i) const    {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}

在这种情况下,如果我打电话说reg[3] = 1;[]将返回对元素#3的引用,而默认的operator=将对引用进行写。

>

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

2 个答案:

答案 0 :(得分:2)

您可以使用代理类来解决此问题。由于无法将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;
    }
};

您班级的operator[]看起来像

Proxy operator[](index_type index)
{
    return Proxy{*this, index};
}

,然后在执行classInstance[index] = value;时调用Proxy的{​​{1}},该参考具有对要调用的对象,要使用的索引以及您还需要的值的引用。 / p>

答案 1 :(得分:0)

您也可以在没有代理类的情况下执行此操作。您可以使operator[]返回对*this的引用,然后重载所述类的=运算符,以对第二个给Write的内容执行operator=论点。

#include <iostream>

struct Foo {
    void Write(int idx, int value) {
        std::cout << "Write(" << idx << ", " << value << ")\n";
    }

    Foo& operator[](int idx) {
        this->index = idx;
        return *this;
    }
    void operator=(int value) {
        this->Write(this->index, value);
    }

    int index;
};

int main() {
    Foo f;
    f[5] = 10;
}

打印:Write(5, 10)