我写了一段代码,但我对它的输出感到困惑:

#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_castnullptr 将返回 std::bad_cast异常如果它转换引用,所以你会确切地知道为什么它失败而不是可能的内存损坏错误。

10-07 20:53