gpt4 book ai didi

c++ - C++中对象的动态成员

转载 作者:行者123 更新时间:2023-11-27 23:54:29 25 4
gpt4 key购买 nike

一个对象的成员被定义为a.b。有没有办法通过 vector 动态获取成员?例如:

struct foo{
std::string bar;
};

vector <foo> baz;

baz[0].bar = "0";

有没有办法在声明 bar 的同时访问 baz.bar? (例子)

void a(std::string b) {
//not sure if this is how it works
std::cout << baz[0].{b};
}

最佳答案

使用字符串访问对象成员的唯一方法是这样的:

void doStuff(std::string_view m) {
if (m == "bar") {
// Do stuff with bar
} else if (/* other members */) {
// Stuff with other members
}
}

看起来很丑。这是丑陋的。我不建议这样做。

C++ 不支持使用字符串查找的原因是因为在运行时,没有关于类型、名称的信息以及关于代码本身的任何其他信息。将此数据添加到编译后的代码中只会导致内存膨胀和二进制膨胀,并且只会在选择的代码中有用。

有多种功能允许类似的语义,但类型安全且比字符串更快。

解决方案一:指向成员的指针

C++ 支持指向成员的指针。它们是一个变量,可以等于一个类的成员。对于给定的实例,您可以动态访问该成员指向的。让我举个例子:

// This declares a pointer to member string data of the class foo
std::string foo::* someMember;

// Some member equals to the member bar
someMember = &foo::bar;

// We declare a foo
foo someFoo;

// Direct access to member
std::cout << someFoo.bar << std::endl;

// Access to the member via the pointer to member
std::cout << someFoo.*someMember << std::endl;

巧妙的是您可以在运行时选择成员:

// Points to a string member of class foo
std::string foo::* someMember;

if ( someCondition ) {
someMember = &foo::bar;
} else {
// baz is another string member of foo
someMember = &foo::baz;
}

foo someFoo;

// Will either access bar or baz depending on the condition
std::cout << foo.*someMember << std::endl;

最棒的是这是类型安全的。指向成员的指针具有明确类的明确类型。这消除了字符串不等于类中的内容或错误类型的问题。

如果您不喜欢声明指向成员的指针的语法,您总是可以使用 auto:

// The type of auto is `std::string foo::*`
auto someMember = &foo::bar;

请注意,someMember 的类型是在编译时推断的,并且在程序执行期间不能更改。

如果我用有效的 C++ 重写你的函数 a,它看起来像这样:

template<typename MemberType>
void a(MemberType foo::* m) {
std::cout << baz[0].*m;
}

类型 MemberType 将在编译时推断出来,就像 auto 一样,因此您的函数可以使用任何类型的成员。要了解有关模板的更多信息,请参阅您首选的 C++ 教程。

方案二:std::unordered_map

有时候你真的需要通过字符串来查找东西。您希望在您的类中动态声明新成员并动态访问它们。在这种情况下,您需要的是映射数据结构:将某种类型的值映射到另一种类型的另一个值的东西。

struct foo {
// We map some strings to some integers
std::unordered_map<std::string, int> values;
};

foo someFoo;

someFoo.values["bar"] = 12;
someFoo.values["baz"] = 15;

// Will print 12, then 15.
std::cout << someFoo.values["bar"] << std::endl;
std::cout << someFoo.values["baz"] << std::endl;

同样,类型安全在这里:您不能不小心将 double 值分配到映射中。查找类型将始终是字符串,关联值将全部是整数。

关于c++ - C++中对象的动态成员,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43671212/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com