提问人:MaxCE 提问时间:10/9/2021 最后编辑:Remy LebeauMaxCE 更新时间:10/9/2021 访问量:864
如何获得基类对象列表并访问派生类字段?
How can I have a list of base class objects and access derived class fields?
问:
假设我有一个基类和两个派生类:
class a {};
class b : a { int a; };
class c : a { int b; };
我有一个基类的列表,并将派生类插入到列表中:
std::list<a> list;
list.emplace_back(b());
list.emplace_back(c());
现在,我想像这样访问:int a
for(auto i : list)
{
i.a = 5;
}
我已经检查了它是什么类,但编译器仍然不允许我访问它。
如何从基类访问派生类中的任何字段?
这个问题已经问过很多次了,但到目前为止,没有一种方法对我有用。
答:
1赞
Remy Lebeau
10/9/2021
#1
首先,您需要一个基类指针列表,否则在将对象插入到列表中时,将对对象进行切片。
然后,您需要根据需要对指针进行类型转换以访问派生类。
如果所有列表元素都指向同一派生类型,则可以使用:static_cast
struct A {};
struct B : A { int a; };
struct C : A { int b; };
std::list<std::unique_ptr<A>> lst;
lst.push_back(std::make_unique<B>());
lst.push_back(std::make_unique<B>());
for(auto &ptr : lst)
{
static_cast<B*>(ptr.get())->a = 5;
}
否则,请改用 在访问派生类类型字段之前测试其类型:dynamic_cast
struct A {};
struct B : A { int a; };
struct C : A { int b; };
std::list<std::unique_ptr<A>> lst;
lst.push_back(std::make_unique<B>());
lst.push_back(std::make_unique<C>());
for(auto &ptr : lst)
{
B *b = dynamic_cast<B*>(ptr.get());
if (b)
b->a = 5;
}
评论
0赞
MatG
10/9/2021
免责声明:如果本文作者不对因支付运行时多态性成本而造成的损失负责,没有任何明显的优势
0赞
MaxCE
10/9/2021
真的很感激这一点,我很惊讶在所有问过这个问题的人中,没有人给出这个答案
0赞
Remy Lebeau
10/9/2021
@MatG 诚然,应该使用多态性来抽象出这样的细节,但也有想要访问特定字段的有效用例。我们在这里分享知识并回答有关如何做特定事情的问题。当然,也要提出更好的选择。
0赞
Remy Lebeau
10/9/2021
@MaxCE SO 上有很多问题,这些问题的答案演示了使用多态性和类型转换指针来访问派生类。只是当按照预期的方式使用多态性时,您首先不需要这样做。
0赞
MatG
10/10/2021
@RemyLebeau那是个小玩笑,你严格地回答了这个问题
评论
std::list<a>
将执行对象切片。没有可访问的派生字段。首先你需要一个或类似的,从那里这个问题可能会有一个答案。std::list<std::unique_ptr<A>>