我写了一段代码,但我对它的输出感到困惑:
#include <iostream>
using namespace std;
class B{
public:
virtual void foo() {cout << "B::foo" << endl;}
};
class D:public B{
public:
virtual void foo() {cout << "D::foo" << endl;}
void disp() {cout << "D::disp" << endl;}
};
void func(B *pb){
D *pd1 = static_cast<D*>(pb);
pd1->foo();
pd1->disp();
}
int main(int argc, char *argv[])
{
B* pb = new B();
func(pb);
return 0;
}
输出是:
B::foo
D::disp
但据我所知,
pb
指向类型B。而且里面没有名为disp()
的函数?那么,为什么它可以访问 D 类中的 disp()
函数呢? 最佳答案
由于 disp()
不访问类的任何成员,因此原则上与在全局命名空间而不是在类中声明它是相同的,因此调用它没有负面影响,即使实例是不合适的类(class)。
你在做什么是将基类的指针向下转换为派生类的指针,即使它没有像这样初始化。如果 disp()
尝试访问 D
中但不在 B
中的类成员,您可能会遇到段错误。
底线:除非您绝对确定指针实际上指向派生类的实例,否则不要使用 static_cast
进行向下转换。如果您不确定,您可以使用 dynamic_cast
,它在不匹配的情况下会失败(但有 RTTI 的开销,所以如果可以,请避免使用它)。
如果转换不正确或抛出 dynamic_cast
,nullptr
将返回 std::bad_cast
异常如果它转换引用,所以你会确切地知道为什么它失败而不是可能的内存损坏错误。