大家好,我是计算机新人林云,不过我更喜欢被称为Linyn
我使用IDE是Clion。
本文是我在学习过程中自己的困惑与发现,才疏学浅,还请指教。
基类函数virtual后,指针有所指,才能调用函数
下面这个程序,基类函数func使用了virtual关键字,但main函数中的指针没有所指之物。
#include<iostream>
using namespace std;
class Base{
public:
virtual void func(){cout << "this's Bace's func." << endl;}
};
class Derive:public Base{
public:
void func(){cout << "this's Derive's func." << endl;}
};
int main(){
Base* ptr1;
// ptr1 = new Base;
ptr1->func();
Derive *ptr2;
// ptr2 = new Derive;
ptr2->func();
}
此时未对两个指针分配内存,终端无输出。
修改后:
int main(){
Base* ptr1;
ptr1 = new Base;
ptr1->func();
ptr1 = new Derive;
ptr1->func();
Derive a;
ptr1 = &a;
ptr1->func();
Derive *ptr2;
ptr2 = new Derive;
ptr2->func();
}
终端输出如下:
this's Bace's func.
this's Derive's func.
this's Derive's func.
this's Derive's func.
从前后对照我们发现,对基类的虚函数与派生类从中继承来的虚函数,当指针没有指向具体对象(或者说分配到具体类型的内存)时,指针无法调用函数。我们猜测,这是由于虚函数正常的发挥作用了,使得程序在指针调用func函数时,进行了动态类型识别RTTI:程序在运行期根据指针所指类型调用函数,如果指针没有所指,则不会调用函数。
为了验证我们的猜想,我将virtual关键字删去,将代码修改为:
class Base{
public:
void func(){cout << "this's Bace's func." << endl;}
};
class Derive:public Base{
public:
void func(){cout << "this's Derive's func." << endl;}
};
int main(){
Base* ptr1;
ptr1->func();
Derive *ptr2;
ptr2->func();
}
终端输出如下:
this's Bace's func.
this's Derive's func.
可以发现,相比最开始没有指向具体对象(或者说分配具体类型的内存)时,我们这个同样没有指向具体对象,但未对func函数进行virtual的程序成功用指针调用了func函数,这是编译期类型识别。
因此可以说明我们的猜想是正确的。
此外,我忘记了调用delete,IDE没有报错……