我花了很多时间试图弄清楚为什么我的代码在运行之后显示“Derived3”而我根本无法理解它。根据我在这里阅读的许多帖子,dynamic_cast应该以某种方式说出指针(在这种情况下是b)是否(在这种情况下)Derived2。但是,它传递了条件,当它应该从Derived2类打印出display()函数时,它会奇怪地显示Derived3类中的那个。我只是想知道为什么程序显示“Derived 3”而不显示任何内容,因为b指针显然没有指向Derived2对象。
#include <iostream>
using namespace std;
class Base
{
int b;
public:
virtual void display()
{
cout<<"Base"<<endl;
}
};
class Derived: virtual public Base{
public:
void display()
{
cout<<"Derived"<<endl;
}
};
class Derived2: virtual public Base{
public:
void display()
{
cout<<"Derived 2"<<endl;
}
};
class Derived3:public Derived,public Derived2{
public:
void display()
{
cout<<"Derived 3"<<endl;
}
};
int main()
{
Base *b = new Derived3();
Derived2 *aux = dynamic_cast<Derived2*>(b);
if(aux)
{
aux->display();
}
return 0;
}
然而,在稍微编辑代码之后,它可以正常工作。
#include <iostream>
using namespace std;
class Base
{
int b;
public:
virtual void display()
{
cout<<"Base"<<endl;
}
};
class Derived: public Base{
public:
void display()
{
cout<<"Derived"<<endl;
}
};
class Derived2: public Base{
public:
void display()
{
cout<<"Derived 2"<<endl;
}
};
class Derived3:public Base{
public:
void display()
{
cout<<"Derived 3"<<endl;
}
};
int main()
{
Base *b = new Derived3();
Derived2 *aux = dynamic_cast<Derived2*>(b);
if(aux)
{
aux->display();
}
return 0;
}
答案 0 :(得分:3)
继承是“Is-a”的关系。
每个 ...//for comprehension logic
} yield (ticketList, eventList)
}
.filter(
(i: TicketList, k: List[SummaryByEvent]) =>
i.tickets.flatMap(x => List(x.event)).diff(k.flatMap(x => List(x.event))) // returns List[Event]
.filter(p => p.dynamicAttribute.get.get("TICKETHOLDER_ONLY") == Some("true")) // also returns List[Event]
都是Derived
和Derived
。按照该模式,每个Base
同时为Derived3
,Derived3
,Derived2
和Derived
。
因此,演员失败是没有意义的。
然后输出最终是Base
上正常虚函数调用的结果。这与最简单的继承示例没有什么不同,例如在这个片段中:
Derived2*
如果您有指向某个基类的指针或引用,则虚函数调用将解析为调用它的对象的实际类型。在您的情况下,这是#include <iostream>
struct A {
virtual void fun() const {
std::cout << 'A';
}
};
struct B : A {
void fun() const {
std::cout << 'B';
}
};
int main () {
const A &a = B();
a.fun(); // prints 'B'
}
指向类型为Derived2*
的子类,因此在后者中查找该函数。
请记住,Derived3
只会更改指针的类型,而不会更改它指向的对象的类型!
答案 1 :(得分:0)
然而,它传递了条件,当它应该从Derived2类打印出display()函数时,它奇怪地显示了Derived3类中的那个。
这是因为动态调度。请记住,display()
被声明为virtual
成员函数。它仍然是所有派生类的virtual
成员函数。
即使您将指针从Base*
转换为Derived*
,基础对象仍然是Derived3
。因此,动态调度机制调用Derived3::display()
。
Derived3::display()
Base *b = new Derived3();
b->display();