C++ 如何从基类指针调用派生类方法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18885224/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to call derived class method from base class pointer?
提问by Ian Thompson
I have a class structure similar to the following
我有一个类似于以下的类结构
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);
};
I want to store instances of the derived classes in a container (standard map) as a collection of A*, then iterate through the container and call methods for each instance.
我想将派生类的实例作为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;
}
The above code produces the following output.
上面的代码产生以下输出。
Hello A1
Hello A1
Where I was expecting
我期待的地方
Hello A1
Hello B1
because I was expecting DoSomethingin Bto hide DoSomethingin A, and because I am storing Apointers, I would expect no object slicing (and looking at the object pointer in the debugger shows that the object has not been sliced).
因为我期待的DoSomething在乙隐藏的DoSomething的一个,因为我存储一个三分球,我希望没有对象切片(并在调试器显示的对象指针找该对象尚未切片)。
I have tried down casting and dynamic casting the pointer to B, but it slices away the data members of Bd.
我试过向下转换和动态转换指向B的指针,但它切掉了Bd的数据成员。
Is there any way to call B::DoSomethingwithout casting the pointer to Bd? And if not, if I have many derived classes of B(e.g. Bda, Bdb, Bdcetc), is there some way to use RTTI to know which derived class to cast it to?
有没有办法在不将指针转换为Bd 的情况下调用B::DoSomething?如果没有,如果我有许多B 的派生类(例如Bda、Bdb、Bdc等),是否有某种方法可以使用 RTTI 来知道将其转换为哪个派生类?
采纳答案by Crowman
You need to make DoSomething()
a virtual
function in both classes to get the polymorphic behavior you're after:
您需要在两个类中创建DoSomething()
一个virtual
函数来获得您所追求的多态行为:
virtual void DoSomething(int i) { ...
You don't need to implement virtual functions in every sub class, as shown in the following example:
您不需要在每个子类中都实现虚函数,如下例所示:
#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;
}
Output:
输出:
I'm A
I'm B
I'm A
我是A
我是B
我是A