2013-07-22 84 views
0
#include <iostream> 
using namespace std; 

class B 
{ 
    B(); 

public: 
    virtual void print()=0; 
}; 

void B::print() 
{ 
    cout << "B::print"; 
} 

int main() 
{ 
    B *bp; 
    bp->B::print(); /* Type-A works fine */ 
    bp->print();  /* Type-B segmentation fault */ 

    return 0; 
} 

在上面的代码中,我试图通过'bp'调用纯虚函数。 现在,在主功能有两种类型的呼叫(A型,B型)的。我的问题是为什么A有效,但B没有。此外,为什么编译器允许在不创建对象的情况下调用非静态函数。纯虚函数的奇怪行为

+0

回复:“*为什么编译器允许在不创建对象的情况下调用非静态函数*”因为编译器假定您知道自己在做什么。编译器没有简单的方法来检查在一般情况下'bp'是否指向有效的东西。 –

+0

根据您的警告级别,您应该看到类似'warning C4700:未初始化的局部变量'bp'used'。 – Derek

回答

4

两个都是不确定的行为,任何事情都有可能发生。 bp未初始化,因此调用它的方法或对其进行解引用是非法的。

5

bp所以你遇到不确定的行为不指向一个有效的对象。在这种情况下,A works but B doesn't是完全有效的未定义行为。请注意,你不能让bpB类型的对象,因为它是一个抽象类。如果您派生了另一个班级并实施了print,那么您可以指向该子对象的bp

1

点:

  1. bp->B::print()可能不起作用,因为:B::print()被显式地给出,并具有有效的指针,该函数本身不具有*this指针涉及。这将被转换为B::print(bp)bp被忽略。

  2. bp->print()可能无法正常工作,因为代码将查找对象bp点,不存在的vptr。该vptr给出了一个错误的位置vtable和函数调用将失败。它被翻译成某事物。如:bp->vptr->vtable['print'](bp)' and you can see both vptr and vtable没有定义。