为什么我能够使用无效的类指针进行函数调用

Sat*_*bir 6 c++ pointers function

在下面的代码片段中,虽然指针未初始化,但仍然可以成功调用

temp *ptr;
ptr->func2();
Run Code Online (Sandbox Code Playgroud)

是由于C++语言属性,还是VC++ 6编译器是犯规的?

class temp {
public:
    temp():a(9){}
    int& func1()
    {
        return a;
    }
    bool func2(int arg)
    {
        if(arg%2==0)
            return true;
        return false;
    }
    int a;
};

int main(int argc, char **argv)
{
    temp *ptr;
    int a;
    cin>>a;
    if(ptr->func2(a))
    {
        cout<<"Good poniner"<<endl;
    }
    ptr->func1(); // Does not crash here
    int crashere=ptr->func1();// But does crash here 
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

Ric*_*dle 14

C++编译器不会阻止您使用未初始化的指针,虽然结果是未定义的,但现实世界中的编译器生成的代码忽略指针未初始化的事实是正常的.

这就是为什么C++相对于其他语言来说既快速又相对危险的原因之一.

func2成功调用的原因是它没有触及它的this指针.从不使用指针值,因此不会导致问题.在func1使用this指针(访问一个成员变量),这就是为什么一个崩溃.


sha*_*oth 7

根据标准,这完全依赖于编译器和未定义的行为.你不应该依赖于此.

调用func2()成功因为在编译时已知调用的确切方法(调用不是虚拟的),并且方法本身不会取消引用指针.所以无效是可以的.

ptr->func1(); // This works
Run Code Online (Sandbox Code Playgroud)

因为指示编译器返回对类成员的引用.为此,它只是将成员的偏移量添加到此指针的无效值,并产生另一个无效指针(引用,它几乎相同).

int crashere=ptr->func1();// Crashes here
Run Code Online (Sandbox Code Playgroud)

因为现在指示编译器通过该无效引用检索值,这会使程序崩溃.