#include <iostream>
using namespace std;
class A
{
int i;
public:
void Hello()
{
cout << "hello" << endl;
}
virtual void vHello()
{
cout<<"vhello"<<endl;
}
};
int main()
{
A* p = NULL;
p -> Hello();
p -> vHello();
}
上面代码会输出“hello”,然后就不会再有输出。
1、为什么p是空指针,还有输出
在上面的程序中,p 明明是一个空指针,为何通过它还能正确调用 A 的成员函数 Hello 呢?p->Hello()实质上p应该是Hello(p),在 Hello 函数中,cout 语句没有用到 this 指针,因此依然可以输出结果。如果 Hello 函数中有对成员变量的访问,则程序就会出错。
http://c.biancheng.net/view/170.html
2、为什么虚函数不输出
虚函数在类中是通过虚函数表来存放的,虚函数表就是指针数组,所以上面对虚函数的访问等价于
*(p->vptr[1])(p);
由于p为NULL,所以无法找到虚函数指针,也就没法调用虚函数了
https://blog.csdn.net/primeprime/article/details/80776625
实例化类的虚函数必须有定义,原因如下:有虚函数作为成员函数的类, 它的实例化-对象, 在运行过程分配到的内存不止是它的成员数据, 还有一个指向该类虚函数表(vtable)的指针, 虚函数表中的每个数据项都是一个虚函数的入口地址; 如果一个对象的虚函数只有声明而没有实现, 就会出现这个虚函数表找不到本应作为其数据项之一的某函数的入口地址, 虚函数表在运行前不能装载完成, 所以产生连接错误!
虚函数的用处
class A
{
public:
void f1()
{
cout<<"A f1"<<endl;
}
virtual void f3()
{
cout<<"A f3"<<endl;
}
};
class B:public A
{
public:
void f1()
{
cout<<"B f1"<<endl;
}
virtual void f3()
{
cout<<"B f3"<<endl;
}
};
int main()
{
B *a = new B;
a->f1();
a->f3();
A *b = new B;
b->f1();
b->f3();
return 0;
}
A *b = new B隐式的派生类到基类的转化,此时b只能访问类A中的成员函数
输出是

本文探讨了在C++中,即使指针p为空,仍能调用非虚函数Hello的原因,因为该函数未使用this指针。对于虚函数,当p为空时,尝试调用会导致错误,因为无法找到虚函数表中的相应入口地址。同时,文章强调了虚函数必须有定义,以避免运行时的连接错误。虚函数的主要作用在于实现多态,允许通过基类指针调用派生类的成员函数。

3037

被折叠的 条评论
为什么被折叠?



