【问题标题】:C++: Best way to access class members using index [duplicate]C ++:使用索引访问类成员的最佳方法[重复]
【发布时间】:2021-05-17 06:43:25
【问题描述】:

我有这样的课:

class cpu
{
    int r0;
    int r1;
    int r2;
    ......
    ......
    int r31;
}

现在有这样一个函数可以设置寄存器的值:

void setVal(string regName, int val)
{
    //Here I want to do something like this
    this->regName = val;
}

寄存器是私有成员,因此无法在外部访问。由于有 32 个成员,因此使用 switch 效率并不高。

【问题讨论】:

  • 您可以使用数组 int r[32]; 而不是 32 个变量。并不能真正解决您的问题,但可以使许多事情变得更容易。但是,您能否澄清一下regName 是什么?也许您可以将其解析为 int 并使用数组,也许不会。
  • 我认为没有办法用字符串做到这一点。我假设regName 代表您的成员名称r0r1,...如果您 - 由于某些原因 - 不能使用数组并进行正常索引,有一种方法可以做指针黑客,但这在技术上UB,你仍然需要一个索引号,而不是一个字符串。如果您真的想使用字符串,则必须以某种方式将其解析为数字或使用查找表。
  • 我刚刚在stackoverflow.com/questions/67563502/… 上回答了您几乎相同的问题,这是重复的还是另一个重复的?
  • 为此目的使用字符串并不是最好的选择——如果有的话,函数应该接受它作为对 const 的引用:std::string const& regname。积分常数更适合;如果您仍然需要比整数常量更好的名称,您可以定义 enumenum class
  • 在您搜索技术解决方案之前,您应该考虑一下您的设计。如果您确实需要通过字符串寻址数据,则可以使用关联容器,例如标准::地图。但这一切都伴随着巨大的开销。特别是因为 std::map 是为动态添加/删除而设计的,它提供了许多不需要的功能,并且在您的用例中效率非常低。 switch 不能用于与 string 进行比较,因此您需要一个效率低得多的字符串比较函数。你真的需要它吗?

标签: c++


【解决方案1】:

如果你不能修改类成员的签名(变量和setVal函数)(或者说你想维护这个接口),最好的解决方案如下:

在类中声明一个地图

#include <map>
class cpu
{
    int r0;
    int r1;
    int r2;
    ......
    ......
    int r31;

    std::map<std::string, int*> regNameToVariable;
}

在构造函数中以这种方式初始化它:

cpu::cpu(){
    regNameToVariable["r0"] = &r0;
    regNameToVariable["r1"] = &r1;
    ......
    ......
    regNameToVariable["r31"] = &r31;
}

那么setVal函数看起来像这样:

void setVal(string regName, int val)
{   
    if(this->regNameToVariable.find(regName) != this->regNameToVariable.end()){ //check if register exist in map
         this->regNameToVariable.at(regName) = val;
    }
}

显然,执行此操作的最佳方法仍然是数组,并将数组的索引作为寄存器的索引。但是如果你不能改变你在问题中写的界面,上面是最好和聪明的解决方案。

【讨论】:

  • 如果地图是静态的并且包含类成员指针可能会更好?只需在程序启动时填写一次,cpu 结构也不必修改。
猜你喜欢
  • 2013-05-25
  • 1970-01-01
  • 1970-01-01
  • 2017-08-24
  • 2012-10-29
  • 2010-11-09
  • 1970-01-01
  • 2018-07-01
  • 2018-07-22
相关资源
最近更新 更多