【问题标题】:How to overload the operators to call a setter function on an operator[] call?如何重载运算符以在 operator[] 调用上调用 setter 函数?
【发布时间】:2019-01-21 14:59:14
【问题描述】:

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

的语法
classInstance[index] = value;

执行

classInstance.cfgfile.Write(index,value)

背景信息;随意跳过。

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

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

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

一切正常...只要 NVRAM 工作正常。这种特定的芯片已经停产,而那些“在野外”的芯片目前开始死于老年。它们的功能对我们的使用意义不大,如果芯片损坏,我们可以将它们的角色转移到闪存上,几乎没有影响(只是多一点闪存磨损)。问题是我们想使用我们的配置格式使用闪存记录,它使用 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= 不带索引,恐怕这个简单的选项无济于事。

【问题讨论】:

  • 代理类。你让classInstance[index] 返回一个带有重载operator= 的辅助类的实例。该类应捕获足够的信息,以便能够从其operator=(value) 调用classInstance.cfgfile.Write(index,value)

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


【解决方案1】:

您可以使用代理类来解决这个问题。由于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; 时,您调用Proxyoperator=,它引用了要调用的对象、要使用的索引以及您还需要的值。

【讨论】:

  • 如果你想另辟蹊径 - value = classInstance[index]; - 只需为 Proxy 类提供一个从引用对象读取的 operator value_type() 转换运算符。
【解决方案2】:

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

#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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-27
    • 1970-01-01
    • 1970-01-01
    • 2011-11-09
    • 1970-01-01
    • 2013-08-02
    • 2015-05-28
    相关资源
    最近更新 更多