C++:深入剖析默认参数

看下列代码执行结果,你猜一猜会输出什么?

#include<iostream>
using namespace std;
struct A {virtual void fun(int a = 10) {cout << "A,a="<<a;}
};
struct B :public A {void fun(int a = 5) {cout <<"B,a="<<a;}
};
int main() {A* a = new B;a->fun();
}

我们看运行结果:

在这里插入图片描述
通过运行结果可以得知发生了多态但是默认参数的值是父类中的。

汇编中默认参数只会在传参中体现为一个字面量所以看编译的中间代码

int main ()
{void * D.53827;struct A * a;int D.53825;bool D.49666;void * D.49598;int (*) () * _1;int (*) () _2;void * _5;void * _6;bool _7;bool _9;int _12;<bb 2> :_5 = operator new (8);_6 = _5;_7 = 1;B::B (_6);_9 = 0;a_10 = _6;_1 = a_10->_vptr.A;_2 = *_1;OBJ_TYPE_REF(_2;(struct A)a_10->0B) (a_10, 10);_12 = 0;<bb 3> :
<L0>:return _12;}void B::B (struct B * const this)
{struct A * _1;int (*) () * _2;<bb 2> :_1 = &this_3(D)->D.49586;A::A (_1);_2 = &_ZTV1B + 16;this_3(D)->D.49586._vptr.A = _2;return;}void A::A (struct A * const this)
{int (*) () * _1;<bb 2> :_1 = &_ZTV1A + 16;this_3(D)->_vptr.A = _1;return;}void B::fun (struct B * const this, int a)
{struct basic_ostream & D.53828;struct basic_ostream & _1;struct basic_ostream & _4;<bb 2> :_4 = std::operator<< <std::char_traits<char> > (&cout, "B,a=");_1 = _4;std::basic_ostream<char>::operator<< (_1, a_5(D));return;}void A::fun (struct A * const this, int a)
{struct basic_ostream & D.53829;struct basic_ostream & _1;struct basic_ostream & _4;<bb 2> :_4 = std::operator<< <std::char_traits<char> > (&cout, "A,a=");_1 = _4;std::basic_ostream<char>::operator<< (_1, a_5(D));return;}

可以看出默认参数在编译时遇到函数调用直接获取了字面量,那么它的生效时间是先于动态多态的,这个时期无论默认参数的字面量存储在代码区还是静态区都不会影响选择,因为这个阶段并没有发生多态也就无从改变默认参数的使用,可以说默认参数就是在编译时期确认函数参数的一种静态行为。

同时这并不是说函数参数是静态的,至少C/C++中函数参数只能是局部的栈区变量(用static声明也会失效),或者可以简单的理解为一种标识符,标识函数调用时传参的要求或者说唯一标识一个函数。

下面一个例子可以证明函数参数不存在static的说法。

#include<iostream>
using namespace std;
struct Test
{int a;
};
struct A {Test& fun1(Test ptr = { 6 }) {return ptr;}Test& fun2(Test ptr) {return ptr;}Test& fun3(static Test ptr) {return ptr;}Test& fun4(static Test ptr = {6}) {return ptr;}Test& fun5() {static Test ptr{ 6 };return ptr;}
};int main() {A a;Test t{ 6 };Test*cur1=&a.fun1();Test*cur2= &a.fun2(t);Test*cur3 = &a.fun3(t);Test*cur4 = &a.fun4();Test*cur5 = &a.fun5();cout << cur1->a << " " << cur2->a << " " << cur3->a << " " << cur4->a<<" "<<cur5->a<<endl;
}

根据返回值可以得出结论static并没有成功修饰到形参,这个其实可以从两方面理解。

  1. 函数形参并没有静态类型的需求。
  2. static修饰词就是那样定义的,详情看这篇

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

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

相关文章

re:从0开始的CSS学习之路 1. CSS语法规则

0. 写在前面 现在大模型卷的飞起&#xff0c;感觉做页面的活可能以后就不需要人来做了&#xff0c;不知道现在还有没有学前端的必要。。。 1. HTML和CSS结合的三种方式 在HTML中&#xff0c;我们强调HTML并不关心显示样式&#xff0c;样式是CSS的工作&#xff0c;现在就轮到C…

编码世界探秘:原反补码与实数表示,含定点、浮点及BCD编码

数值的编码表示 整数编码表示 在计算机中&#xff0c;因为只有0和1这两种形式&#xff0c;但为了表示数的正&#xff08;&#xff09;&#xff0c;负&#xff08;-&#xff09;号&#xff0c;就要将数的符号以0和1编码。 通常把一个数的最高位定义为符号位&#xff0c;用0表…

Zephyr NRF7002 实现AppleJuice

BLE的基础知识 ble的信道和BR/EDR的信道是完全不一样的。但是范围是相同的&#xff0c;差不多也都是2.4Ghz的频道。可以简单理解为空中有40个信道0~39信道。两个设备在相同的信道里面可以进行相互通信。 而这些信道SIG又重新编号&#xff1a; 这个编号就是把37 38 39。 3个信道…

Python中的while循环,知其然知其所以然

文章目录 while循环结构1.用循环打印1 ~ 100步骤解析2. 1 ~ 100的累加和3.死循环1. 用死循环的方法实现 1 ~ 100累加和 4. 单向循环(1)打印 一行十个小星星*(2)通过打印一个变量的形式,展现一行十个小星星(3)一行十个换色的星星 ★☆★☆★☆★☆★☆(4)用一个循环,打印十行十列…

5、从 CSV 到 ChatGPT 的完整分析报告,只需 5 个简单步骤

从 CSV 到 ChatGPT 的完整分析报告,只需 5 个简单步骤 数据分析是一项耗时的活动。使用 ChatGPT,我们可以在短时间内进行数据汇总、数据预处理、数据可视化等。 无论您从事什么行业,在数据驱动时代,知道如何分析数据比以往任何时候都更加重要。数据分析将使企业能够保持竞…

【C语言 - 哈希表 - 力扣 - 相交链表】

相交链表题目描述 给你两个单链表的头节点 headA 和 headB &#xff0c;请你找出并返回两个单链表相交的起始节点。如果两个链表不存在相交节点&#xff0c;返回 null 。 图示两个链表在节点 c1 开始相交&#xff1a; 题目数据 保证 整个链式结构中不存在环。 注意&#xff0…

【VTKExamples::PolyData】第二十期 ImplicitModeller

很高兴在雪易的CSDN遇见你 VTK技术爱好者 QQ:870202403 前言 本文分享VTK样例ImplicitModeller技术,并解析接口vtkImplicitModeller,希望对各位小伙伴有所帮助! 感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步! 你的点赞就是我的动力(^U^)ノ~YO 1. I…

JVM 性能调优 - JVM 参数基础(2)

查看 JDK 版本 $ java -version java version "1.8.0_151" Java(TM) SE Runtime Environment (build 1.8.0_151-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.151-b12, mixed mode) 查看 Java 帮助文档 $ java -help 用法: java [-options] class [args...] …

Java基础(二十四):网络编程

Java基础系列文章 Java基础(一)&#xff1a;语言概述 Java基础(二)&#xff1a;原码、反码、补码及进制之间的运算 Java基础(三)&#xff1a;数据类型与进制 Java基础(四)&#xff1a;逻辑运算符和位运算符 Java基础(五)&#xff1a;流程控制语句 Java基础(六)&#xff1…

电脑服务器离线安装.net framework 3.5解决方案(错误:0x8024402c )(如何确定当前系统是否安装NET Framework 3.5)

问题环境&#xff1a; 日常服务的搭建或多或少都会有需要到NET Framework 3.5的微软程序运行框架&#xff0c;本次介绍几种不同的安装方式主要解决运行在Windows 2012 以上的操作系统的服务。 NET Framework 3.5 是什么&#xff1f; .NET Framework是微软公司推出的程序运行框架…

Web html和css

目录 1 前言2 HTML2.1 元素(Element)2.1.1 块级元素和内联(行级)元素2.1.2 空元素 2.2 html页面的文档结构2.3 常见标签使用2.3.1 注释2.3.2 标题2.3.3 段落2.3.4 列表2.3.5 超链接2.3.6 图片2.3.7 内联(行级)标签2.3.8 换行 2.4 属性2.4.1 布尔属性 2.5 实体引用2.6 空格2.7 D…

Android Studio导入项目 下载gradle很慢或连接超时

AS最常见的问题之一就是下载gradle非常慢&#xff0c;还经常出现下载失败的情况&#xff0c;没有gradle就无法build项目&#xff0c;所以一定要先解决gradle的下载问题&#xff0c;下面教大家两种常用方法 手动下载压缩包并替换 1、关闭Android Studio&#xff0c;复制下面的网…