代码之家  ›  专栏  ›  技术社区  ›  SF.

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

  •  3
  • SF.  · 技术社区  · 6 年前

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

    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损坏或手动禁用,则可以写入文件。


    网络中充满了这样的例子:只需返回对它的引用,就可以使用操作符[]来设置给定的值。为了 example :

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

    在这种情况下,如果我打电话,说, reg[3] = 1; 这个 [] 将返回对元素3和默认值的引用 operator= 会给参考信写的很好。

    但是因为我不能返回对文件中某个键的引用( .WriteKey() 只执行完整的写入,返回成功或错误),以及 运算符= 不接受索引,恐怕这个简单的选项没有帮助。

    2 回复  |  直到 6 年前
        1
  •  2
  •   NathanOliver    6 年前

    您可以使用代理类来解决这个问题。自从 value 不能传给 classInstance 我们需要制造一个物体 operator[] 可以返回将得到的值 价值 并知道要将该操作应用到哪个实例。使用

    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;
        }
    };
    

    你们班的 操作员[ ] 看起来像

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

    然后当你这样做的时候 classInstance[index] = value; 你打电话 Proxy operator= 它引用了要调用的对象、要使用的索引以及您还需要的值。

        2
  •  0
  •   Stack Danny    6 年前

    您也可以在没有代理类的情况下执行此操作。你可以做 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)