请考虑以下示例代码。
#include <iostream>
using namespace std;
class base
{
public:
void func()
{
cout << "base::func()" << endl;
}
};
class derived : public base
{
public:
void func()
{
cout << "derived::func()" << endl;
}
};
void dummy(base *bptr)
{
derived *dptr = static_cast<derived*> (bptr);
dptr->func();
}
int main()
{
base bob1;
derived dob1;
dummy(&dob1); //Line1
dummy(&bob1); //Line2
}
在Line1中,我将派生类对象的地址传递给函数dummy
,该函数获取指向基类对象的指针。因此,函数static_cast
中的dummy
是安全的。
在Line2中,我将基类对象的地址传递给函数。因此,函数static_cast
中的dummy
不安全。
但是当我执行代码时,程序运行正常。我想,通过单词not safe
,程序应该在运行时崩溃。但没有发生崩溃。
这是我得到的输出。
derived::func()
derived::func()
程序在运行时没有崩溃的原因是什么?
答案 0 :(得分:10)
因为未定义的行为意味着任何事情都可能发生,不一定是崩溃。
在我看过的大多数编译器中,调用非virtual
方法不能访问NULL
指针上的类成员,但它仍未定义。
答案 1 :(得分:6)
C ++的核心概念之一是未定义的行为。当您执行导致未定义行为的操作时,例如静态转换一个不指向转换类型对象的指针,程序的行为实际上是未定义的:标准没有定义任何特定的行为。平台不需要做任何特定的事情,根据标准,它显示的任何行为都可以。
这种未定义的行为包括默默地为您做正常行为。无法保证分段错误或任何其他诊断。