虚函数的作用和实现原理
程序员文章站
2024-03-21 11:48:34
...
虚函数的作用和实现原理
1. virtual虚函数作用
- 实现C++三大特性之一的多态
- 当父类的某个函数,需要在子类中重写时,就在父类中定义为虚函数;
- 这样当定义一个父类指针指向子类时,就能动态地调用某子类的(被重写)函数;
纯虚函数: 父类中没有定义,而在子类中需要用到,就定义为:virtual void f() = 0;
class A {
public:
virtual void func() = 0; // 这种写法叫纯虚函数
};
class B: public A {
public:
void func() {
cout << "this is B" << endl;
}
};
int main()
{
A *p = new B;
p->func();
return 0;
}
打印结果为:
this is B
2. 虚函数原理–虚函数表(virtual table)
- 父类的实例化存储了一个虚函数指针(v_ptr),它指向了一张虚函数表(v_table),这张表记录了到每个子类的对应关系;当通过父类指针调用子类方法时,就会调用v_ptr和v_table;
3. 构造函数与折构函数能否申明为虚函数?
- 场景1: B *p = new B; (B是A的一个子类, 如下代码)
- 首先明确调用顺序:
- 构造函数:先调用父类的,再调用子类的;不可以为虚函数
- 折构函数:先调用子类的,再调用父类的;可以是虚函数
- 调用构造函数时,该子类的内存空间还未分配,父类的虚函数表没有任何意义;
class A {
public:
A() {cout << "A()" << endl;}
~A() {cout << "~A()" << endl;}
};
class B: public A {
public:
B() {cout << "B()" << endl;}
~B() {cout << "~B()" << endl;}
};
int main()
{
B *p = new B;
delete p;
return 0;
}
执行结果:
/Users/mac/CLionProjects/testC++/cmake-build-debug/testC_
A()
B()
~B()
~A()
- 场景2:父类指针指向子类: A *p = new B;
- 若A的折构函数不是虚函数:
- delete p时,只释放了A的内存,会造成子类B的内存部分泄漏;
- 若A的折构函数是虚函是:
- 将先通过A的虚函数表找到B的折构函数,从而先释放B的内存,最后释放A;
- 因此在这种场景下,推荐将父类的折构函数申明为虚函数
推荐阅读
-
虚函数的作用和实现原理
-
多重继承的构造函数和析构函数的执行顺序(包含虚基类)
-
Fragment的懒加载实现原理和封装
-
《递归求阶乘和》要求实现一个计算非负整数阶乘的简单函数,并利用该函数求 1!+2!+3!+...+n! 的值。
-
JAVA(JDK)动态代理和Cglib代理的实现原理
-
Java多线程之异步Future机制的原理和实现
-
Java多线程之异步Future机制的原理和实现
-
php实现自定义中奖项数和概率的抽奖函数示例
-
java实现简单的窗体和密码验证(传参,事件机制和事件监听的作用过程) 博客分类: java图形界面基础,事件机制 javaJFrame监听器事件机制
-
php实现自定义中奖项数和概率的抽奖函数示例