当dynamic_cast工作时,程序应该失败/崩溃

时间:2018-03-24 00:01:54

标签: c++

在我看来,下面的程序应该崩溃,但它不仅有效,而且显示正确的结果(" derv被称为")。

#include <iostream>
using namespace std;
class base 
{
 public:
  virtual ~base(){}
};
class derv: public base 
{
 public:
   void f() { cout << "derv is called" <<endl;}
};
int main() {
  base* p = new base();
  derv *d1 = dynamic_cast<derv*>(p);

 // Since p point to base , so d1 should return nullptr 
 //calling any function using d1, should fail/crash 
 //but why the following line is working ?? 

 d1->f();
}

抱歉,我忘了在上一篇文章中添加几行:如果我添加一个数据成员并尝试访问它,给我分段错误,我认为这是正确的行为。我的问题是,为什么访问数据成员会改变行为?当没有访问变量时,调用&#34; f()&#34;功能是成功的同时功能&#34; f()&#34;使用数据成员访问时会出现分段错误?这是未定义的行为吗?

class derv: public base 
{
 public:
  int x = 0 ; // Added new member,  c++11
  void f() { cout << "derv is called " << x << endl;} //access it here
};

2 个答案:

答案 0 :(得分:3)

f不是虚函数。尝试调用f时,程序不必查找虚函数表,因此无论如何都要调用该方法。

如果您尝试检查thisf的指针值,它将为nullptr

答案 1 :(得分:3)

您解除引用d1的程序是未定义的行为,这是一个NULL指针:

base* p = new base();
derv *d1 = nullptr;
d1 = dynamic_cast<derv*>(p);

if(nullptr == d1) // condition succeeds which means d1 is nullptr
    cout << "nullptr" << endl; 

安全编程是程序员的任务,而不是编译器的任务,所以在使用之前检查一个好的程序:

// avoiding error prones and UBs
if(nullptr != d1)
    d1->f();