假设我有一个带虚函数的空类:
class Base
{
public:
virtual void Foo(){std::cout << "this is the base class";}
}
然后我有一个继承自Base
并覆盖Foo()
的类:
class Derived : public Base
{
public:
void Foo(){std::cout << "this is the derived class";}
}
然后还有一些其他类包含Base
列表:
class OtherClass
{
public:
std::vector<Base> listOfBases; //note it's not std::list<Derived>
}
如何循环listOfBases
并为Foo()
课程而不是Derived
课程调用Base
?现在,如果我要说listOfBases[i].Foo();
,那么这是基类会打印,但我希望从Derived
类中重写一个来打印。
我可以把它设为Derived
而不是Base
的列表,这样可以修复它,但是我会将这些继承的类称为各种不同的东西,所以我需要一个列表Base
。
那么如何从其基类列表中调用重写函数?
答案 0 :(得分:3)
您需要使用Base*
列表(即指向基础的指针),或者最好使用std::unique_ptr<Base>
或std::shared_ptr<Base>
。
原因是因为C ++对象模型和复制。派生类必须至少与其基类一样大(它们可以是相同的大小,具体取决于派生类是否为空)。由于C ++在向vector
添加项目时使用复制(或可能在C ++ 11中移动),因此必须为n Base
个对象分配足够的空间。由于vector
几乎总是围绕简单array
的包装,因此尝试将{可能不同大小的} Derived
对象添加到array
个Base
个对象中是未定义的行为。
答案 1 :(得分:0)
获取指向每个基类的指针,然后向下传播一个Derived类。它被称为向下转换,因为在UML图中,通常在派生类之上绘制基类。
for ( auto q = listOfBases.begin(); q != listOfBases.end(); ++q )
{
Base* pBase = &(*q); // Get pointer to Base class. Can't downcast on object.
Derived* pDerived = dynamic_cast<Derived*>(pBase); // Downcast
pDerived->Foo(); // Call Foo() of Derived
}