为什么未初始化的指针在 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。但是为什么?
第二个例子有两个地方发生了变化:
- 我通过将其虚拟化来使用覆盖函数。
- 该函数以指针作为参数。
在第一种情况下,您的 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;
}
您编写的代码表现出未定义的行为。遇到 未定义行为 的代码可能:
- 分段错误
- 向屏幕输出奇怪的字符。
- 因不同的优化级别和编译器而异
- 完全按照您的意愿工作。
小伙伴们请查看下面的代码:
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。但是为什么?
第二个例子有两个地方发生了变化:
- 我通过将其虚拟化来使用覆盖函数。
- 该函数以指针作为参数。
在第一种情况下,您的 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;
}
您编写的代码表现出未定义的行为。遇到 未定义行为 的代码可能:
- 分段错误
- 向屏幕输出奇怪的字符。
- 因不同的优化级别和编译器而异
- 完全按照您的意愿工作。