我有这样的代码:虚拟关键字使得人迹罕至的方法从派生的对象
#include <iostream>
class Super{
public:
virtual void showName();
};
class Special1 : public Super {
public:
void showName();
void sayHello();
};
class Special2 : public Super {
public:
void showName();
void sayGoodbye();
};
void Super::showName() {
std::cout << "I'm super!" << std::endl;
}
void Special1::showName() {
std::cout << "I'm special1" << std::endl;
}
void Special1::sayHello() {
std::cout << "Hello" << std::endl;
}
void Special2::showName() {
std::cout << "I'm special2" << std::endl;
}
void Special2::sayGoodbye() {
std::cout << "Goodbye" << std::endl;
}
int main() {
Super *oSpec=new Super;
Special1 *o1=static_cast<Special1 *>(oSpec);
Special2 *o2=static_cast<Special2 *>(oSpec);
oSpec->showName();
o1->showName();
o2->showName();
o1->sayHello();
o2->sayGoodbye();
delete oSpec;
return 0;
}
当我运行它,它显示了这个输出:
I'm super!
I'm super!
I'm super!
Hello
Goodbye
但是,如果我删除virtual
关键字来自Super
类的声明:
class Super{
public:
/*virtual*/ void showName();
};
输出成为正确之一:
I'm super!
I'm special1
I'm special2
Hello
Goodbye
然后,我的问题是,为什么virtual
关键字的存在使得指针o1
和o2
运行的方法Super::showName()
,而不是Special1::showName()
或Special2::showName()
?
使用上面的static_cast <>是未定义的行为。该代码已损坏,仅适用于编译器及其当前标志的奇想。 –
代码会导致未定义的行为,除非指向的对象实际上是一个“Special#”实例,否则不能将'Super *'强制转换为'Special#*'对象,而在您的情况下则不是。 –