在我看来,下面的程序应该崩溃,但它不仅有效,而且显示正确的结果(" 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
};
答案 0 :(得分:3)
f
不是虚函数。尝试调用f
时,程序不必查找虚函数表,因此无论如何都要调用该方法。
如果您尝试检查this
内f
的指针值,它将为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();