【问题标题】:C++: How to access a member variable whose name is stored in an arrayC ++:如何访问名称存储在数组中的成员变量
【发布时间】:2021-08-06 08:24:28
【问题描述】:

假设我有一个这样的字符串数组:

string registers[2] = {"r0","r1"}

还有这样的结构:

struct cpu {
    int r1;
}

我尝试过这样的事情:

cpu *p = (cpu*)malloc(sizeof(cpu));
cout << p->registers[1] << endl;

但这给出了编译错误。如何实现?

编辑:问题描述

我需要使用索引访问 cpu 类的成员,所以我想我可以将成员的名称放在一个数组中,然后使用索引获取成员的名称

【问题讨论】:

  • 您可以使用int r[2]; 而不是int r1;,这可能会使拥有寄存器数组变得更容易。
  • 如果您在运行时绝对需要通过字符串名称访问成员,请考虑使用包含成员指针的std::(unordered_)map 作为映射元素类型。
  • 描述你的功能需求可能比粗略地勾画你的方法更好。你的设计有很多缺陷,很难猜出real problem是什么。
  • @JaMiT 我需要使用索引访问 cpu 类的成员,所以我想我可以将成员的名称放在一个数组中,然后使用索引获取成员的名称
  • @LipunPanda 但是你的cpu 班级只有一个成员......当只有一个成员时决定访问哪一个成员有多难?也许你过度简化了你的例子?

标签: c++ arrays struct


【解决方案1】:

这是一个使用字符串到 cpu 成员映射的示例:

#include <iostream>
#include <string>
#include <map>
using namespace std;

struct cpu {
    int r0;
    int r1;
};

map<string,int cpu::*> registers = {
    {"r0",&cpu::r0},
    {"r1",&cpu::r1}
};

int main()
{
    cpu x{0, 1};
    cout << " x.r1 = " << x.r1 << ",  x.*registers[\"r1\"] = " << x.*registers["r1"] << "\n";
    x.*registers["r1"] = 2;
    cout << " x.r1 = " << x.r1 << ",  x.*registers[\"r1\"] = " << x.*registers["r1"] << "\n";
    
    cpu *p = &x;
    p->*registers["r1"] = 3;
    cout << "p->r1 = " << p->r1 << ", p->*registers[\"r1\"] = " << p->*registers["r1"] << "\n";


    return 0;
}

在这里试试:https://onlinegdb.com/d2KqBH0Mo

这里是一个,就像你原来的例子一样,使用一个整数索引到一个数组中:

#include <iostream>
#include <string>
#include <map>
using namespace std;

struct cpu {
    int r0;
    int r1;
};

int cpu::* registers[] = {
    &cpu::r0,
    &cpu::r1
};

int main()
{
    cpu x{0, 1};
    cout << " x.r1 = " << x.r1 << ",  x.*registers[1] = " << x.*registers[1] << "\n";
    x.*registers[1] = 2;
    cout << " x.r1 = " << x.r1 << ",  x.*registers[1] = " << x.*registers[1] << "\n";
    
    cpu *p = &x;
    p->*registers[1] = 3;
    cout << "p->r1 = " << p->r1 << ", p->*registers[1] = " << p->*registers[1] << "\n";


    return 0;
}

在这里试试:https://onlinegdb.com/3hWpmEijs

【讨论】:

    【解决方案2】:

    您的代码格式完全错误。表达式p-&gt;registers 使用默认运算符-&gt;,它要求左手运算符是指向类型的指针,该类型的成员名称用作右手运算符(registers)。您的cpu 不包含registers

    无论出于何种原因,模仿您想要的行为的步骤:

    1. 设计一种方法,通过索引或指向成员的指针将特定 stringcpu 的成员相关联。
    2. 将字符串值映射到索引或成员指针。
    3. C++ 允许使用成员运算符封装它,这将导致像 p["r0"] 这样的东西产生对 r0 的引用。

    在最简单的情况下,当所有元素都属于同一类型时,您可以只使用std::map 或类似设计的类,例如

    struct cpu {
        std::map<std::string, int> registers;
    
        // constructor initializes the map
        cpu() : registers ( { {"r0", 0}, 
                              {"r1", 0} 
                            }) 
        {}
    };
    

    这里的表达式p-&gt;registers["r0"] 会为您提供与“r0”键关联的值的引用等。

    NB创建cpu对象应该是

    cpu *p = new cpu();
    

    【讨论】:

    • @LipunPanda 您在这里,但老实说,请考虑您所做的事情,我不了解提供适当解决方案的实际任务,而且您显然在基础知识方面遇到困难。这个例子有自己的成本
    • Jerry's answer 似乎优于我:只有一个全局映射,只填充一次,而不是每个实例,最重要的是,没有在结构上修改 cpu 结构,如果该类应该映射到一些特定的内存,例如。 G。 (auto cpu0 = new(SpecificCPU0Address) cpu();(在这种情况下,没有更多的 CPU 寄存器被映射访问覆盖)。
    • @aconcagua 我同意,但这仅适用于只有一种 cpu 的情况。如果内存映射为真,那么我们实际上是在创建一个适配器。
    • 啊,我的错...Duplicate answer 更清楚地暗示了这个方向,错过了这个问题(至少看起来)更通用...
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-06
    • 2017-03-11
    • 1970-01-01
    • 2017-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多