[C++][Warning] Default arguments on virtual or override methods are prohibited

1 引言

C++作为一门强大的编程语言,广泛用于开发各种类型的应用程序,特别是在面向对象编程领域。在C++中,虚函数和重写函数是面向对象编程的关键概念,它们允许我们建立强大的继承层次结构和多态行为。默认参数则为函数提供了额外的灵活性,使我们可以为函数的参数提供默认值。然而,当这两个概念结合在一起时,可能会引发意想不到的问题和错误。
如果你曾经在C++编程中遇到过 Default arguments on virtual or override methods are prohibited 的警告,那么本文将为你提供宝贵的见解和解决方案。

2 基本概念

在C++中,虚拟函数和重写函数是面向对象编程的关键概念之一。它们允许你创建多态性,这意味着你可以在基类中定义一个函数,然后在派生类中重写(覆盖)这个函数,以实现不同的行为。

2.1 虚函数

虚函数是在基类中声明为 **virtual **的成员函数。这意味着虚拟函数的行为取决于实际对象的类型,而不是引用或指针的类型。在基类中声明虚拟函数时,使用 virtual 关键字。

class Base {
public:
virtual void foo() {// 基类的虚拟函数实现
}
};

2.2 重写函数

当你在派生类中重新定义(重写)基类中的虚拟函数时,它被称为重写函数。重写函数的声明必须与基类中的虚拟函数完全匹配,包括参数列表和返回类型。一般建议在定义重写函数时,使用 **override **关键字。

class Derived : public Base {
public:void foo() override {// 派生类的虚拟函数实现,覆盖基类的foo()}
};

3 错误场景重现

以下测试修改自 C++虚函数中的默认参数_虚函数尽量不要提供默认参数-CSDN博客,可以帮助你直观的看出虚函数带默认参数可能带来的问题。

class Base {
public:Base();~Base();virtual void setNumber(int num = 2) = 0;
};class A :public Base {
public:A();~A();virtual void setNumber(int num = 4) override{qDebug() << num;};
};
// Demo 1
Base* a1 = new A;
a1->setNumber(9);// Demo 2
Base* a2 = new A;
a2->setNumber();// Demo 3
A* a3 = new A;
a3->setNumber();

显然,以上代码我们期望的输出是:

9 
4
4

但是实际上我们会输出:

9
2
4

4 分析原因

Demo 2可以看出,虚函数调用了派生类重写的方法,但是没有调用派生类的默认参数。这个结果看起来有些矛盾:虚函数允许在运行时动态绑定到子类,因此父类才得以实现调用派生类重写后的方法。那么为什么没有调用派生类的默认参数呢?
在C++中,虚拟函数和重写函数的特性意味着编译器在运行时动态地选择要调用的函数版本,这是通过虚函数表(vtable)和指针来实现的。当你在派生类中重写基类的虚拟函数时,编译器将替换虚函数表中的相应条目,以便正确调用派生类的版本。
当在虚函数中使用默认参数时,默认参数的值通常在编译时确定,而虚拟函数调用是在运行时解析的。这就引发了潜在的问题,即默认参数的值在编译时确定,但虚拟函数的选择是在运行时进行的。当编译一个调用虚拟函数的地方时,编译器需要知道要调用哪个版本的函数,但默认参数的值在这时还不可知。因此虚函数会调用编译时的默认参数作为变量传入,这很显然和我们的目的相违背。
C++是一门开放的语言,你几乎可以做你想做的任何事情。编译器默认你已经知道了这个知识,不会禁止你在虚函数中使用默认参数。类似MSVC的编译器此时将抛出警告: Default arguments on virtual or override methods are prohibited.

5 解决方案

5.1 避免在虚拟和重写方法中使用默认参数

最简单的方法是避免在虚拟或重写方法中使用默认参数。

class Base {
public:virtual void foo(int x) {// 基类的虚拟函数实现}
};

5.2 使用函数重载

如果你需要提供多个版本的函数,可以使用函数重载来实现,而不是在虚拟函数中使用默认参数。

class Base {
public:virtual void foo() {// 基类的虚拟函数实现}virtual void foo(int x) {// 基类的虚拟函数实现}
};

6 总结

在本文中,我们深入探讨了C++中的警告 “Default arguments on virtual or override methods are prohibited”,并解释了为什么在虚拟或重写方法中使用默认参数可能会导致问题。希望通过避免在虚拟或重写方法中使用默认参数,你能够提高代码的可维护性和稳定性,编写更健壮和高质量的C++代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/16515.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

《NoSQL数据库技术与应用》MongoDB数据库操作

《NoSQL数据库技术与应用》 教学设计 课程名称&#xff1a;NoSQL数据库技术与应用 授课年级&#xff1a; 20xx年级 授课学期&#xff1a; 20xx学年第一学期 教师姓名&#xff1a; 某某老师 2020年5月6日 课题 名称 第3章 MongoDB数据库操作 计划学时 14课时 内容 分析 如果说…

如何在.NET中集成SignalR

SignalR 简介 SignalR是一个开放源代码库&#xff0c;可用于简化向应用添加实时Web功能&#xff0c;实时Web功能使服务器端代码能够将内容推送到客户端。 SignalR开源库&#xff1a;https://github.com/SignalR/SignalR SignalR 应用场景 需要高频次从服务器获取信息的应用&am…

QML_Switch控件_3选2的控制算法

QML_Switch控件_3选2的控制算法 import QtQuick 2.12 import QtQuick.Window 2.12 import QtQuick.Controls 2.5Window {visible: truewidth: 400height: 400title: qsTr("Hello World")property int num: 0Row {spacing: 10Switch {id: switch1onCheckedChanged: {…

Android基础-初识Android系统架构

Android系统架构详解 Android系统作为一款广泛应用于智能手机、平板电脑等设备的操作系统&#xff0c;其架构的设计对于系统的稳定性、可扩展性和用户体验至关重要。Android系统架构是一个复杂的层次结构&#xff0c;旨在实现硬件与软件之间的高效协同工作&#xff0c;为用户提…

redis如何查看参数值

在Redis中&#xff0c;查看参数值可以使用CONFIG GET命令。以下是查看Redis参数值的详细步骤和格式化的回答&#xff1a; 1. 启动Redis客户端 首先&#xff0c;你需要打开Redis的客户端。这通常可以通过在终端或命令提示符中输入redis-cli命令来实现。 2. 连接到Redis服务器…

找出缺失的观测数据

代码实现&#xff1a; 在缺失的 n 个观测数据中&#xff0c;有 y 个观测数据是 x1&#xff0c;其余观测数据都是x int* missingRolls(int *rolls, int rollsSize, int mean, int n, int *returnSize) {int m rollsSize;int sum mean * (n m);int missingSum sum;for (int i…

Java进阶:详解与实战Java Stream API

Java进阶&#xff1a;详解与实战Java Stream API &#x1f31f; Java进阶&#xff1a;详解与实战Java Stream API &#x1f31f;摘要引言一、Java Stream API介绍&#x1f4da;1. 什么是Java Stream API&#xff1f;2. Java Stream API支持的功能3. 使用Java Stream API的优势…

Python-3.12.0文档解读-内置函数id()详细说明+记忆策略+常用场景+巧妙用法+综合技巧

一个认为一切根源都是“自己不够强”的INTJ 个人主页&#xff1a;用哲学编程-CSDN博客专栏&#xff1a;每日一题——举一反三Python编程学习Python内置函数 Python-3.12.0文档解读 目录 详细说明 概述 参数 返回值 特性 实现细节&#xff08;CPython&#xff09; 安全…

F12 网络请求类型:Fetch与XHR的区别

F12 网络请求类型&#xff1a;Fetch与XHR的区别 引言 在Web开发中&#xff0c;浏览器的F12开发者工具是调试网络请求的重要工具。通过F12&#xff0c;我们可以查看各种类型的网络请求&#xff0c;包括fetch和XMLHttpRequest&#xff08;XHR&#xff09;。这两种技术都用于在浏…

Linux——Linux服务管理

服务管理大作业要求&#xff1a; 基本拓扑如下&#xff1a; 按照要求完成基本的系统管理任务&#xff1a; 完成所有系统的主机名、网络配置&#xff1b; 本次作业共需要3台虚拟机&#xff0c;分别作为客户端、综合应用服务器、存储服务器。三台虚拟机操作系统均为CentOS-Stream…

5.2网安学习第五阶段第二周回顾(个人学习记录使用)

本周重点 ①HIDS的基本应用(suricata) ②Suricata的基本应用 ③Suricata的流量检测 ④Suricata的https流量检测 ⑤利用Elastic整合Suricata日志 ⑥利用Wazuh对Suricata主动响应 本周主要内容 ①HIDS的基本应用(suricata) 1、NIDS 1、定义&#xff1a;网络入侵检测系统…

算法简单笔记

本人大二下学期报了中国大学生计算机设计大赛、珠澳计算机设计大赛、区块链软件设计大赛、蓝桥杯......然后一直准备着设计大赛的比赛&#xff0c;根本没空管蓝桥杯&#xff0c;就省考前准备了一星期&#xff0c;感觉是没有希望了&#xff0c;但是很莫名其妙的就拿了蓝桥杯Java…

悲痛都会过去,唯有当下值得珍惜

在生活的长河中&#xff0c;我们都会经历各种各样的悲痛与挫折&#xff0c;无论是来自原生家庭的困扰&#xff0c;婚姻中的曲折&#xff0c;还是小时候的创伤、男女关系中的纠葛、校园时期的霸凌。然而&#xff0c;当我们回首过去&#xff0c;曾经以为无法逾越的痛苦&#xff0…

通过css实现------简单边框流动特效

效果展示 代码部分 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta http-equiv"X-UA-Compatible" content"IEedge"><meta name"viewport" content"widthdevice…

C++学习/复习5--构造函数与初始化/static成员/友元/内部类/匿名对象/编译器的拷贝构造优化

一、本章概要 二、再谈构造函数 1.构造体赋初值与初始化 2.初始化列表与初始化 2.1定义 2.2注意事项与举例 3.explicit关键字与构造函数 3.1隐式类型转换 也叫做自动类型转换 这种转换通常是从存储范围小的类型到存储范围大的类型&#xff0c;或者是从低精度的数值类型到高…

简述vue-loader是什么?使用它的用途有哪些

vue-loader是一个webpack的加载器(loader)&#xff0c;主要用于将Vue组件的单文件(.vue文件)转换为JavaScript模块。使用vue-loader的主要用途包括&#xff1a; 解析.vue文件&#xff1a;vue-loader能够解析.vue文件中的模板、样式和脚本&#xff0c;并将它们分离出来进行处理…

python爬虫学习(1)——初识爬虫

520那天我向心仪的女孩要微信&#xff1a;“女神&#xff0c;能给我你的微信号吗&#xff1f;” 女神&#xff1a;“爬&#xff01;&#xff01;&#xff01;&#xff01;” 从那天开始&#xff0c;我就决定要学好爬虫&#xff0c;爬到女神微信号&#xff01;&#xff01;&…

引入安全生产培训云平台,实现“人人讲安全、个个会应急”

引入安全生产培训云平台&#xff0c;旨在全面提升企业及员工的安全意识与应急处理能力&#xff0c;通过数字化手段实现“人人讲安全、个个会应急”的目标。这一平台的构建和应用&#xff0c;不仅促进了安全知识的普及&#xff0c;还极大提高了培训的效率与效果。以下是该平台几…

python 匿名函数 lambda

匿名函数 可以不使用def语句去定义&#xff0c;可以写到简单的表达式 语法结构 lambda 参数&#xff1a;表达式 简单使用 可以写推导式&#xff0c;三目运算符&#xff0c;但是不可以写x1 result lambda i, j: i*jprint(result(2, 3))# 输出 6 lambda运用filter list1 [3…

驱动开发之字符设备开发

1.概念 字符设备是 Linux 驱动中最基本的一类设备驱动&#xff0c;字符设备就是一个一个字节&#xff0c;按照字节 流进行读写操作的设备&#xff0c;读写数据是分先后顺序的。比如我们最常见的点灯、按键、IIC、SPI&#xff0c; LCD 等等都是字符设备&#xff0c;这些设备的驱…