[C++ PRIMER知识梳理] 15.3 虚函数

本文详细梳理了C++中的虚函数概念,通过实际项目中的例子,阐述了基类与派生类如何利用虚函数实现多态性,探讨了虚函数在继承和动态类型绑定中的关键作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/* *
 *	普通成员函数, 可以只声明不定义.
 *
 *	虚函数, 必须要有定义, 因为编译器无法确定运行时会使用到哪个虚函数.
 *
 *
 *	当某个虚函数通过指针或引用被调用时, 编译器产生的代码直到运行时才能
 *
 *	确定应该调用哪个版本的函数. 被调用的函数是与绑定到指针或引用的对象
 *
 *	相匹配的那个.
 *
 *	动态绑定只发生在用指针或引用调用虚函数时, 如果直接用普通类型调用函数
 *
 *	在编译时就可以确定其调用的版本.
 *
 *	指针或引用的静态类型与动态类型不同, 是C++多态性的根本所在, 只有当我们
 *
 *	使用指针或引用调用虚函数时, 才会在运行时解析该调用, 也只有在这种情况下
 *
 *	对象的静态类型和动态类型才会不同.
 *
 *
 * 	1. 当在派生类中覆盖了某个虚函数时, 可以再一次使用virtual来指出函数的性质,
 *
 * 	但不是必须, 因为该函数在所有派生类中都为虚函数.
 *
 *	2. 一个派生类的函数如果覆盖了某个继承而来的虚函数, 则它的形参类型必须与被
 *
 *	它覆盖的基类函数要完全一致.其返回类型也必须与基类匹配, 除非其返回类型是其
 *
 *	自身的引用或指针.
 *
 *	override在覆盖未生效时, 会报错.
 *
 *	final可以放在函数声明后, 任何对该函数的覆盖都会报错.
 *
 *
 *	虚函数的默任实参, 派生类和基类中是独立的, 若用基类指针或引用调用某个虚函数,
 *
 *	那么生效的会是基类中定义的默认实参, 即使该对象的动态类型是派生类.
 *
 *	如果虚函数使用默认实参, 最好保证派生类和基类中定义的默认实参一致.
 *
 *	我们可以用域运算符来强行调用某个版本的虚函数, 该行为在编译时完成解析.
 *
 *	通常只有在成员函数或友元函数中, 需要用域运算符来回避虚函数机制.
 *
 *	如果一个派生类的虚函数需要调用其基类版本, 如果没有使用域运算符, 就会产生无限
 *
 *	递归.
 *
 * */

补充一下, 最近项目中用到的一个例子:

 

先是基类的定义:

#ifndef JSONPARSE_H
#define JSONPARSE_H

class Json;

class JsonParse
{
        public:
                virtual int ParseToJson(Json &json) = 0;
                virtual int ParseTo(Json &json) = 0;
};

#endif

再是派生类的定义:

#include "JsonParse.h"
#include "Json.h"

//    这个例子成功运行, 说明派生类的虚函数中, 可以修改自身的数据
//    Json.h里的内容是最近正在写的一个Json库, 写完后可能会放到github上
//    有兴趣的话可以看看

class Test : public JsonParse
{
        public:
        int data;
        int ParseToJson(Json &json) override
        {
                data = 2;
                return 0;
        }
        int ParseTo(Json &json) override
        {
                data = 1;
                return 0;
        }
};

int main()
{
        Test t;
        JsonParse &jp = t;
        Json json;
        jp.ParseToJson(json);
        Test &tr = dynamic_cast<Test &>(jp);
        printf("%d\n", tr.data);
        jp.ParseTo(json);
        printf("%d\n", tr.data);
        return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值