理解C++中的多态性

rjee0c15  于 2023-03-25  发布在  其他
关注(0)|答案(1)|浏览(99)

我有两个类,DerivedADerivedB,它们派生自同一个Base类。这两个类都持有指向对象的指针,对象分别属于两种数据类型之一,TypeATypeB。这些数据类型派生自同一个基本类型BaseType
Base类中,我有一个(抽象的)getter用于这些指针。该getter在每个派生类中被重写,并被指定为它们应该返回派生的数据类型。
main函数中,我定义了一个vector,它包含指向两个派生类的对象的指针。但是当我迭代该vector时,我只得到BaseType指针,而不是预期的TypeA/TypeB指针。
以下MWE说明:

#include <iostream>
#include <vector>

using namespace std;

class BaseType {};
class TypeA : public BaseType {};
class TypeB : public BaseType {};

class Base {
public:
  virtual BaseType* GetObject() = 0;
};

class DerivedA: public Base {
public:
  TypeA* object = new TypeA();
  TypeA* GetObject() override {
    cout << "i'm comming from DerivedA" << endl;
    return object;
  }
};

class DerivedB: public Base {
public:
  TypeB* object = new TypeB();
  TypeB* GetObject() override {
    cout << "i'm comming from DerivedB" << endl;
    return object;
  }
};

int main() {
  vector<Base*> vec = {new DerivedA(), new DerivedB()};
  for (auto* item : vec){
    auto* obj_ptr = item->GetObject();
    cout << "I have an object of type " << typeid(obj_ptr).name() << endl;
  }
}

其产生以下输出:

i'm comming from DerivedA
I have an object of type P8BaseType
i'm comming from DerivedB
I have an object of type P8BaseType

现在,我有两个问题,我希望它们的答案能帮助我理解C++中的多态性是如何工作的:
1.为什么对每个向量项的GetObject()的调用都清楚地落在正确的覆盖中,但没有分别返回TypeA*TypeB*,而是返回一个指向BaseType的指针?
1.我需要如何修改代码以分别获得指向类型TypeATypeB的指针?

e3bfsja2

e3bfsja21#

您的示例中有两个问题。
首先,BaseType不是多态的,所以typeid不会使用RTTI。添加一个虚函数解决了这个问题。

class BaseType {
public:
    virtual ~BaseType() = default;
};

其次,typeid会尽可能检查其操作数的动态类型,但不会检查特殊情况下的指针。obj_ptr本身明确地属于BaseType *类型,即使它指向一个派生对象。另一方面,*obj_ptr是一个BaseType &typeid(*obj_ptr)很乐意查询它的动态类型。
See the resulting code on Godbolt

相关问题