Let's say I have a base class and two derived classes:
class a {};
class b : a { int a; };
class c : a { int b; };
And I have a list of the base class, and I insert the derived class into the list:
std::list<a> list;
list.emplace_back(b());
list.emplace_back(c());
Now, I want to access int a
like this:
for(auto i : list)
{
i.a = 5;
}
I already have checks in place to see what class it is, but the compiler is still not letting me access it.
How can I access any field in the derived class from the base class?
This question has been asked many times, but none of the methods have worked for me so far.
CodePudding user response:
First, you need a list of base class pointers, otherwise you will slice the objects when you insert them into the list.
Then, you need to type-cast the pointers to access derived classes as needed.
If all of the list elements are pointing at the same derived type, you can use 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;
}
Otherwise, use dynamic_cast
instead to test the derived class type before accessing its fields:
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;
}