2013-01-13 108 views
1

我在使用虚拟方法时遇到问题。当我打电话f它不起作用。为什么?为什么我的虚函数没有被调用?

#include <iostream> 

struct A { 
    virtual void f() const { std::cout << "In A"; } 
    virtual ~A() {}; 
}; 

struct B : A { 
    void f() const { std::cout << "In B"; } 
}; 

int main() 
{ 
    A* a = new A(); 

    B* b = dynamic_cast<B*>(a); 

    (*b).f(); 


    delete a; 
} 

它根本不打印任何东西,我也没有得到任何错误。我做错了什么?

+1

总是检查'dynamic_cast'的结果。 – chris

+1

B是A,但A不是B. – Bart

回答

10

什么是错误的是你没有检查是否重新调整指针是NULL

dynamic_cast告诉你a指出的实际物体是b的类型,这显然不是。在这种情况下,它会返回给您NULL

基本上,您正在取消引用NULL指针,导致未定义行为不幸的是您不会崩溃。

当您使用语言提供的功能时,应按照标准规定的方式使用它。使用dynamic_cast保证返回指针的NULL检查。

您的指针a实际上应该指向派生类对象b。您需要:

A* a = new B(); 
    B* b = dynamic_cast<B*>(a); 

而且,你的代码必须检查返回指针:

if(b != NULL) 
     (*b).f(); 
+0

如果你不想检查'NULL'(但你为什么不这样做?),你可以'dynamic_cast'改为引用类型;那么失败的转换会抛出异常而不是返回NULL。 –

7

这条线:

B* b = dynamic_cast<B*>(a); 

给你一个空指针,因为a不以事实上指向B

下面一行是未定义的行为。 (你很幸运,没有任何事情发生。)

+0

我该如何解决? –

+0

@大卫,有一个有效的'B'对象。 – chris

+0

完全取决于你要做什么。你可以做'A * a =新B;'...... – aschepler

相关问题