1

假设我有一个带有虚函数的空类:

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.

那么如何从其基类列表中调用被覆盖的函数呢?

4

2 回答 2

3

您需要使用一个列表Base*(即指向基址的指针),或者最好std::unique_ptr<Base>使用std::shared_ptr<Base>.

其原因是因为 C++ 对象模型和复制。派生类必须至少与其基类一样大(它们可以是相同的大小,具体取决于派生类是否为空)。由于 C++ 在向 a 添加项目时利用复制(或可能在 C++11 中移动) ,因此它必须为 n 个对象vector分配足够的空间。Base由于 avector几乎总是一个简单的包装器array,因此尝试将一个(可能不同大小的)Derived对象添加到一个对象arrayBase是未定义的行为。

于 2012-12-17T00:47:14.547 回答
0

获取指向每个基类的指针,然后将其向下转换为派生类。之所以称为向下转换,是因为在 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
} 
于 2012-12-17T00:53:27.107 回答