class A
{
public:
virtual void func() {
cout<<" func():: in class A"<< endl;
}
void func1(){
cout<<"func1():: in class A";
}
};
class B: public A {
public:
void func() {
cout<<" func():: in class B"<< endl;
}
void func1(){
cout<<"func1():: in class B";
}
};
int main()
{
A a;
A* pa = &a;
B* pb = dynamic_cast<B*>(pa);
pb->func1();
return 0;
}
虽然pb
指向的是不完整的类型,dynamic_cast
将返回null
。
但是为什么它不会在这种情况下崩溃?
答案 0 :(得分:2)
由于func1
类中的B
无法访问任何成员变量(或虚函数),因此它不会使用隐式this
指针,因此,这种情况下,不会崩溃。
请注意,这是未定义的行为,因此它可能会在不同的编译器(或编译器版本)中崩溃(或做一些意外的事情),因此不要依赖此行为。
答案 1 :(得分:1)
您有A *
指向实际指向A
实例的A *
实例,而不是B
。这就是dynamic_cast
返回类型为B *
的空指针的原因,它与这些不完整类型或任何内容无关(在链接代码中,A
和B
都是完整类型),因此这是dynamic_cast
的定义行为。但是之后会访问空指针;一个聪明的编译可以知道dynamic_cast
可以在那一点失败,pb->func1();
可以做任何事情,包括不导致空指针异常或任何东西,甚至调用{ {1}}关于非pb1->func
的内容。
不完整类型的示例是:
B
现在如果用G ++编译它,你就得到了
#include <iostream>
using namespace std;
class A {
public:
virtual void func() {
cout << "func():: in class A" << endl;
}
void func1(){
cout<< "func1():: in class A";
}
};
class B;
int main() {
A a;
A* pa = &a;
B* pb = dynamic_cast<B*>(pa);
return 0;
}
这是所有理智的C ++编译器都会拒绝这样的代码。