如何重载运算符以在 operator[] 调用中调用 setter 函数?
How to overload the operators to call a setter function on an operator[] call?
如何重载 class 的运算符,以便使用
的语法
classInstance[index] = value;
执行
classInstance.cfgfile.Write(index,value)
背景资料;随意跳过。
我们开发的应用程序使用内存映射访问一段 NVRAM - 实际上,映射的只是两个寄存器,地址和数据。您写入地址寄存器,然后写入或读取数据寄存器。初始化后,读取和写入由 class 的简单 [] 重载执行,该 class 持有对内存段的引用。你引用实例的 [] 给出你想要读写的单元格的命名空间索引,它会做它的事情。
int& IndirectMemory::operator[](RTCMemIndex idx)
{
*midx_reg = idx;
return *mdata_reg;
}
(代码中删除了不相关的元素,如互斥锁和健全性检查)。
一切正常...只要 NVRAM 正常工作。这个特定的芯片已经停产,'out in the wild' 目前已经开始老化。它们的功能对我们的使用意义不大,如果芯片损坏,我们可以将它们的角色转移到闪存而几乎没有影响(只是闪存磨损多一点)。事情是我们想使用我们的配置格式的闪存记录,它使用 getter 和 setter。
int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);
在代码的许多地方,我们通过 IndirectMemory[Some_Register] = Some_Value;
写入各种经常更改的内容来调用 NVRAM,我们希望通过重启来保持。我想保留此语法和行为,但如果检测到 NVRAM 已损坏或通过配置条目手动禁用,则能够写入文件。
网络上充斥着使用 operator[] 仅通过 return 引用它来设置给定值的示例。对于 example:
unsigned long operator [](int i) const {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}
在这种情况下,如果我调用 reg[3] = 1;
,[]
将 return 引用元素#3,默认 operator=
将写入参考就好。
但由于我无法 return 对文件中的键的引用(.WriteKey()
只执行完整的写入,return 成功或错误),并且 operator=
不带索引,恐怕这个简单的选项不会有帮助。
您可以使用代理 class 来解决这个问题。由于 value
不能传递到 classInstance
我们需要创建一个对象 operator[]
可以 return 它将获得 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;
}
};
你的class的operator[]
看起来像
Proxy operator[](index_type index)
{
return Proxy{*this, index};
}
然后当您执行 classInstance[index] = value;
时,您调用 Proxy
的 operator=
,它具有对要调用的对象的引用、要使用的索引以及您还需要的值.
您也可以在没有代理的情况下执行此操作 class。您可以使 operator[]
return 成为对 *this
的引用,然后重载所述 class 的 =
运算符以对提供给的任何内容执行 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)
如何重载 class 的运算符,以便使用
的语法classInstance[index] = value;
执行
classInstance.cfgfile.Write(index,value)
背景资料;随意跳过。
我们开发的应用程序使用内存映射访问一段 NVRAM - 实际上,映射的只是两个寄存器,地址和数据。您写入地址寄存器,然后写入或读取数据寄存器。初始化后,读取和写入由 class 的简单 [] 重载执行,该 class 持有对内存段的引用。你引用实例的 [] 给出你想要读写的单元格的命名空间索引,它会做它的事情。
int& IndirectMemory::operator[](RTCMemIndex idx)
{
*midx_reg = idx;
return *mdata_reg;
}
(代码中删除了不相关的元素,如互斥锁和健全性检查)。
一切正常...只要 NVRAM 正常工作。这个特定的芯片已经停产,'out in the wild' 目前已经开始老化。它们的功能对我们的使用意义不大,如果芯片损坏,我们可以将它们的角色转移到闪存而几乎没有影响(只是闪存磨损多一点)。事情是我们想使用我们的配置格式的闪存记录,它使用 getter 和 setter。
int TCfgFile::ReadKey(std::string Key);
void TCfgFile::WriteKey(std::string Key,int data);
在代码的许多地方,我们通过 IndirectMemory[Some_Register] = Some_Value;
写入各种经常更改的内容来调用 NVRAM,我们希望通过重启来保持。我想保留此语法和行为,但如果检测到 NVRAM 已损坏或通过配置条目手动禁用,则能够写入文件。
网络上充斥着使用 operator[] 仅通过 return 引用它来设置给定值的示例。对于 example:
unsigned long operator [](int i) const {return registers[i];}
unsigned long & operator [](int i) {return registers[i];}
在这种情况下,如果我调用 reg[3] = 1;
,[]
将 return 引用元素#3,默认 operator=
将写入参考就好。
但由于我无法 return 对文件中的键的引用(.WriteKey()
只执行完整的写入,return 成功或错误),并且 operator=
不带索引,恐怕这个简单的选项不会有帮助。
您可以使用代理 class 来解决这个问题。由于 value
不能传递到 classInstance
我们需要创建一个对象 operator[]
可以 return 它将获得 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;
}
};
你的class的operator[]
看起来像
Proxy operator[](index_type index)
{
return Proxy{*this, index};
}
然后当您执行 classInstance[index] = value;
时,您调用 Proxy
的 operator=
,它具有对要调用的对象的引用、要使用的索引以及您还需要的值.
您也可以在没有代理的情况下执行此操作 class。您可以使 operator[]
return 成为对 *this
的引用,然后重载所述 class 的 =
运算符以对提供给的任何内容执行 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)