如何重载类的运算符,以便使用
的语法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=
不带索引,因此恐怕这个简单的选项无济于事。
答案 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)