从 base 的特定派生类型调用特定函数

Call specific function from a specific derived type from base

本文关键字:调用 函数 类型 派生 base      更新时间:2023-10-16

让我们这样说吧.....

struct A {virtual void something(){cout <<"I'm A.";}};
struct B, A 
{
void something(){cout << "I'm B.";}
void somethingFromB(){cout << "I'm from B.";}
}
int main()
{
A a = B();
//Now, here is where I want to call "somethingFromB" from A. How to?
}

因此,如此处所示,我们有"某物",可以从类型为"A"的对象调用,就像类型为"B"的对象一样。我现在创建了一个类型为"A"的对象,称为a,并将其设置为"B"。如何像处理常规 B 对象一样使用它,并能够从中调用"somethingFromB"?

编辑---我想我可以使用:

A* a = new B(); ((B*)a)->somethingFromB();

这似乎编译得很好:/

问题是,如果你定义一个 A 对象,它将保持一个 A 对象。

如果将派生对象复制到其中,则会执行隐式转换。 事实上,B 中的A子对象将被复制。这种效果称为切片

您还可以定义自己的构造函数或赋值运算符,以从 B 中生成 A。但是,无论您以何种方式控制此副本,最终,targe 对象仍然是 A。

这就是为什么A a = B();真的会创建一个 A 并表现得像一个 A。

如果要使用多态性并保留类型,可以使用指针或引用:

A& ra = b;  // reference to an A object 
ra.something();  // ==> it's a B because ra refers to the original object
A* pa = &b;  // pointer to an A object
pa->something();  // ==> it's a B because pa points to the original object 
shared_ptr<B> spb = make_shared<B>();  // creates a shared pointer to a newly allocated B object
shared_ptr<A> spa = spb;  
spa->something();  // ==> it's a B again 

注意:这种多态行为仅适用于基类型的虚函数(与真实对象的成员函数的动态绑定(。对于任何非虚函数,para将使用A的函数。而且您不能调用未为 A 定义的 B 函数。