如何从基类指针调用派生类方法

How to call derived class method from base class pointer?

本文关键字:调用 派生 类方法 指针 基类      更新时间:2023-10-16

我有一个类似于以下内容的类结构

class A
{
public:
    A(void);
    ~A(void);
    void DoSomething(int i)
    {
        std::cout << "Hello A" << i << std::endl;
    }
};
class B : public A
{
public:
    B(void);
    ~B(void);
    void DoSomething(int i)
    {
        std::cout << "Hello B" << i << std::endl;
    }
};
class Ad : public A
{
public:
    Ad(void);
    ~Ad(void);
};
class Bd : public B
{
public: 
    Bd(void);   
    ~Bd(void);
};

我想将派生类的实例作为 A* 的集合存储在容器(标准映射)中,然后遍历容器并为每个实例调用方法。

#include "A.h"
#include "B.h"
#include "Ad.h"
#include "Bd.h"
#include <map>
int main(int argc, char** argv)
{
    std::map<int,A*> objectmap;
    objectmap[1] = new Ad();
    objectmap[2] = new Bd();
    for (std::map<int,A*>::iterator itrobject = objectmap.begin();
         itrobject!=objectmap.end(); itrobject++)
    {
        itrobject->second->DoSomething(1);
    }
    return 0;
}

上面的代码生成以下输出。

Hello A1
Hello A1

我期待的地方

Hello A1
Hello B1

因为我期望 B 中的 DoSomething 在 A 中隐藏 DoSomething,并且因为我存储了 A 指针,所以我不希望对象切片(并且查看调试器中的对象指针显示对象尚未切片)。

我已经尝试过向下转换并将指针动态转换为 B,但它会切掉 Bd 的数据成员。

有没有办法在不将指针投射到 Bd 的情况下调用 B::D oSomething?如果没有,如果我有许多 B 的派生类(例如 Bda、BdbBdc 等),有没有办法使用 RTTI 来知道将其转换为哪个派生类?

你需要在两个类中DoSomething()一个virtual函数,以获得你所追求的多态行为:

virtual void DoSomething(int i) { ...

您不需要在每个子类中实现虚函数,如以下示例所示:

#include <iostream>
class A {
    public:
        virtual void print_me(void) {
            std::cout << "I'm A" << std::endl;
        }
        virtual ~A() {}
};
class B : public A {
    public:
        virtual void print_me(void) {
            std::cout << "I'm B" << std::endl;
        }
};
class C : public A {
};
int main() {
    A a;
    B b;
    C c;
    A* p = &a;
    p->print_me();
    p = &b;
    p->print_me();
    p = &c;
    p->print_me();
    return 0;
}

输出:


我是 我是乙
我是