为什么未初始化的指针在 C++ 程序中起作用?

WHY does an uninitialised pointer work in C++ programs?

小伙伴们请查看下面的代码:

class Human
{ 
public:
    void chat(Human h)
    {
        cout << "human";
    }

    void chat(ComputerScientist c)
    {
        cout << "computer";
    }
};

class ComputerScientist : public Human
{
};

//Main function below
int main()
{
    Human* p, p1;
    //Uninitialized pointer above;

    p->chat(p1); //It shows perfectly the result without ANY error!
}

但是,如果我在派生 class ComputerScientist 中创建一个函数来覆盖人类的函数,事情就会变得棘手。

class Human
{
public:
    virtual void chat(Human* h)
    {
        cout << "about the weather";
    }

    virtual void chat(ComputerScientist* c)
    {
        cout << "about their own computer illiteracy";
    }
};

class ComputerScientist : public Human
{
public:
    virtual void chat(Human* h)
    {
        cout << " about computer games";
    }

    virtual void chat(ComputerScientist* c)
    {
        cout << " about others’ computer     illiteracy";
    }
};

和我用的是同一个main函数,貌似是空指针那一行的segmentation fault。但是为什么?

第二个例子有两个地方发生了变化:

  1. 我通过将其虚拟化来使用覆盖函数。
  2. 该函数以指针作为参数。

在第一种情况下,您的 class 是一个 POD(普通旧数据)并且您的聊天功能没有 dereference/access 任何成员变量 - 因此它似乎工作正常(这是一个不好的做法虽然 - 由于未定义的行为)。在 virtual functions each object has vtable 的情况下,它需要一个有效的指针才能工作——因此会导致错误。

您也可以通过以下方式让您的第一个案例出错:

class Human 
{ 
    private:
        int n;
    public:

    void chat(Human h) 
    {
        cout << "human #" << n << endl;
    }

    void chat(ComputerScientist c) 
    {
        cout << "computer";
    }
};

class ComputerScientist:public Human{};

int main()
{
    Human* p,p1;
    //Uninitialized pointer above;
    p->chat(p1);//It shows perfectly the result without ANY error!

    return 0;
}

您编写的代码表现出未定义的行为。遇到 未定义行为 的代码可能:

  • 分段错误
  • 向屏幕输出奇怪的字符。
  • 因不同的优化级别和编译器而异
  • 完全按照您的意愿工作。