当前位置: 首页 > wzjs >正文

网站空间的选择如何使用华为云虚拟主机建设网站

网站空间的选择,如何使用华为云虚拟主机建设网站,东莞做网站 信科网络,怎么制作网页设计作业文章目录 引言函数重载函数重载的使用函数重载的原理extern “C” 静态多态 总结 引言 通过00【C 入门基础】前言得知,C是为了解决C语言在面对大型项目的局限而诞生: C语言面对的现实工程问题(复杂性、可维护性、可扩展性、安全性&#xff0…

文章目录

  • 引言
  • 函数重载
    • 函数重载的使用
    • 函数重载的原理
      • extern “C”
    • 静态多态
  • 总结


引言

通过00【C++ 入门基础】前言得知,C++是为了解决C语言在面对大型项目的局限而诞生:

C语言面对的现实工程问题(复杂性、可维护性、可扩展性、安全性)

C语言为了实现不同类型的加法,只能定义多个函数:

//C语言:
int add_int(int a, int b)              //对两int类型相加
{return a + b;
}
double add_double(double a, double b)  //对两double类型相加
{return a + b;
}
int add_10_int_ptr(void *a)      //对void*类型强转之后加10
{return *a + 10;
}
int main()
{add_int(1, 2);add_double(1.2, 2.3);return 0;
}

平时写写还可以,面对大型项目问题就暴露出来了:

  1. 多个类似功能(加法)的函数,在各个角落被调用,但是函数名称不同,命名冗余,代码可读性下降。​(对调用者来说复杂)
  2. C语言的泛型,由于对void*没有检查,使用起来不安全(安全性):
#include <stdio.h>
// 类型不安全的打印函数
void unsafe_print(void* data, char type)   //C语言使用void*,也实现了一个函数接收不同类型(泛型编程),但是使用起来不安全。
{switch(type) {case 'i': // 假设 'i' 代表 intprintf("Integer: %d\n", *(int*)data);break;case 'f': // 假设 'f' 代表 floatprintf("Float: %f\n", *(float*)data);break;default:printf("Unknown type\n");}
}
int main() 
{int a = 10;float b = 3.14;// 正确使用(需要确保类型匹配)unsafe_print(&a, 'i');unsafe_print(&b, 'f');// 类型错误的使用(编译器不会警告)unsafe_print(&b, 'i'); // 错误!把 float 当作 int 解释unsafe_print(&a, 'f'); // 错误!把 int 当作 float 解释return 0;
}

函数重载

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型不同的问题。

函数重载的使用

#include<iostream>
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{cout << "int Add(int left, int right)" << endl;return left + right;
}
double Add(double left, double right)
{cout << "double Add(double left, double right)" << endl;return left + right;
}
// 2、参数个数不同
void f()
{cout << "f()" << endl;
}
void f(int a)
{cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{cout << "f(char b, int a)" << endl;
}
int main()
{Add(10, 20);Add(10.1, 20.2);f();f(10);f(10, 'a');f('a', 10);return 0;
}

函数重载,需要参数类型不同、参数个数不同、参数类型顺序不同。

思考:

  1. 以下函数构成重载吗?
int Add(int a, char b)
{cout << "Add(int a, char b)";
}
int Add(int b, char a)
{cout << "Add(int b, char a)";
}

不构成,我们的参数的顺序类型个数都没有变化,参数名不起决定作用。

  1. 以下函数构成重载吗?
int f()
{cout << "f()";
}
int f(int a = 0)
{cout << "f(int a = 0)";
}

构成,但是有错,因为调用的时候有歧义:

int main()
{f();      //有多个 重载函数 "f" 实例与参数列表匹配:return 0;
}
  1. 以下函数构成重载吗?
void Func(int a = 10)
{cout<<"void Func(int a = 10)"<<endl;
}
void Func(int a)
{cout<<"void Func(int a)"<<endl;
}

不构成,不满足重载条件,虽然不传参只能调用到第一个带缺省值的函数,但是如果传参的话就会有调用冲突:“Func”: 重定义默认参数 : 参数 1

函数重载的原理

在从代码变为可执行程序的过程的汇编阶段,会生成符号表,符号表主要功能之一就是帮助后续的链接器找到和解析符号(如函数和全局变量)。
编译链接过程
那么每个函数都会生成它自己对应的符号,C++在这里用了采用了有别于C语言的符号生成方式,才得以实现函数重载:

  • 采用C语言编译器编译后结果:
    C语言编译后的结果
  • 采用C++编译器编译后结果:
    在这里插入图片描述

可以看到,C++最终生成的符号表,是不同于C语言的,其实它生成符号表的时候,考虑了函数的参数,也就最终导致,参数类型不同、参数个数不同、参数类型顺序不同的同名函数生成的符号不相同,那么最后链接器去找到对应函数的符号进行链接的时候,就可以区分重载的函数!!!

疑问:我们只是换了个编译器,为什么说是C++语言的行为?
这由C++语言规范明确规定的机制,强制所有的C++编译器执行。

windows下vs编译器对函数名字修饰规则相对复杂难懂,所以我们使用Linux演示,但道理都是类似的,我们就不做细致的研究了。

extern “C”

由于C和C++编译器对函数名字修饰规则的不同,在有些场景下可能就会出问题,比如:

  1. C++中调用C语言实现的静态库或者动态库,反之亦然。
  2. 多人协同开发时,有些人擅长用C语言,有些人擅长用C++。

在这种混合模式下开发,由于C和C++编译器对函数名字修饰规则不同,可能就会导致链接失败,在该种场景下,就需要使用extern “C”。在函数前加extern “C”,意思是告诉编译器,将该函数按照C语言规则来编译。下面演示一个在C++工程中使用C语言静态库的例子:

///cal.h/
#pragma once
/*
* 注意:
* 在实现该库时,并不知道将来使用该静态库的工程是C语言工程还是C++工程
* 为了能在C/C++工程中都能使用,函数声明时需加上extern "C"
*
* __cplusplus:是C++编译器中定义的宏,即用该宏来检测是C工程还是C++工程
*
* 
* #ifdef __cplusplusextern "C"{#endif// 要导出函数的声明#ifdef __cplusplus}#endif作用:如果是C++工程,编译器已经定义_cplusplus宏,编译时该宏是可以被识别的,被声明的函数就被
extern "C"修饰了,此时C++编译就知道,静态库中的函数是按照C的方式编译的,这样在链接时就会按照C的方式找函
数名字如果是C工程,编译器未定义_cplusplus宏,编译时该宏无法被是被,则条件编译就无效,函数就
不会被extern "C"修饰
*/#ifdef __cplusplus
extern "C"
{
#endifint Add(int left, int right);int Sub(int left, int right);
#ifdef __cplusplus
}
#endif
///cal.cpp/
#include "cal.h"int Add(int left, int right)
{return left + right;
}
int Sub(int left, int right)
{return left - right;
}
///libUser.cpp/
#include "./../../StaticLib/StaticLib/cal.h"
#pragma comment(lib, "./../../StaticLib/Debug/StaticLib.lib")
#include <iostream>
using namespace std;int main()
{int ret = Add(10, 20);cout << ret << endl;ret = Sub(30, 20);cout << ret << endl;return 0;
}

如果在实现静态库时,cal.h中的函数没有使用extern "C"修饰就会报错:

#pragma once
int Add(int left, int right);
int Sub(int left, int right);

1>TestCalc.cpp
1>TestCalc.obj : error LNK2019: 无法解析的外部符号 “int __cdecl Add(int,int)” (?
Add@@YAHHH@Z),函数 _main 中引用了该符号
1>TestCalc.obj : error LNK2019: 无法解析的外部符号 “int __cdecl Sub(int,int)” (?
Sub@@YAHHH@Z),函数 _main 中引用了该符号
1>D:\WorkStations\Gitee\cppLesson\TestCalc\Debug\TestCalc.exe : fatal error LNK1120: 2
个无法解析的外部命令

思考:

  1. C语言中为什么不能支持函数重载?
    C语言没有生成符号表是考虑参数的规范,所以链接器最后会将所有同名不同参的函数,认为是同一个。
  2. C++中能否将一个函数按照C的风格来编译?
    可以,为了向前兼容,即即使有了C++,C语言的代码也可以被C++的编译器运行。
  3. C++程序中被extern "C"修饰的函数,就会按照C语言规则来编译,用C语言的方式来生成符号表,那么它是不是不可以做函数重载了?
    是的,C语言规则生成符号表时不考虑函数的参数,所以被修饰的函数将不可被重载。

静态多态

多态,就是同一个接口(函数调用)可以根据对象类型的不同而执行不同的操作,说白了就是看人下菜碟。
多态又分为静态多态和动态动态,静态多态在编译时绑定,动态多态在运行时绑定。

我们的函数重载,就正是多态的一种,因为它根据参数类型变化,可以执行不同操作,它在我们编译时,便通过符号表确定,所以它是一种静态多态!!

总结

1.函数重载,解决C语言的同功能但不同命函数的命名冗余和一些安全性问题。
2.函数重载的使用方式,是定义一个同名,但是参数类型不同、参数个数不同、参数类型顺序不同的函数。
3.函数重载的原理是:C++汇编时生成的符号表,每个函数的符号都考虑了函数的参数去生成,所以参数类型不同、参数个数不同、参数类型顺序不同的同名函数之间可以被区分。
4.函数重载,是一种多态,静态多态。


本文章为作者的笔记和心得记录,顺便进行知识分享,有任何错误请评论指点:)。


文章转载自:

http://HGZT9ZbD.rcwbc.cn
http://M2xttb4B.rcwbc.cn
http://SvDmSVzP.rcwbc.cn
http://Q7MmNUlp.rcwbc.cn
http://qX6Yp2y0.rcwbc.cn
http://XiGUENt8.rcwbc.cn
http://wS8pjtGY.rcwbc.cn
http://YkHf8bXc.rcwbc.cn
http://XUYXQTgn.rcwbc.cn
http://YbfENoMU.rcwbc.cn
http://J0ReClrF.rcwbc.cn
http://zd2BXHfs.rcwbc.cn
http://w5jyworx.rcwbc.cn
http://sdwB531C.rcwbc.cn
http://VZeUF8wL.rcwbc.cn
http://8MBxIFr2.rcwbc.cn
http://m1YLbuKt.rcwbc.cn
http://bKA65AAP.rcwbc.cn
http://bfUPX5vO.rcwbc.cn
http://l5vGsr1l.rcwbc.cn
http://rLYFjpMg.rcwbc.cn
http://UH6jxwVt.rcwbc.cn
http://C70ocLj6.rcwbc.cn
http://sofWqqU4.rcwbc.cn
http://Cgl6muXI.rcwbc.cn
http://C8fxaXsW.rcwbc.cn
http://KN3Pmtw8.rcwbc.cn
http://rAyTcQDo.rcwbc.cn
http://WFX1gsyS.rcwbc.cn
http://GaGt3US3.rcwbc.cn
http://www.dtcms.com/wzjs/640687.html

相关文章:

  • wamp 多网站WordPress是静态吗
  • 网站正在备案中4.1进行网站建设与推广
  • 山东网站建设网站设计广告一般用什么软件
  • 佛山市网站建设 乾图信息科技访问自己做的网站
  • 网站建设要花多少钱网站空间和虚拟主机
  • wordpress文章页不显示侧边郑州seo顾问外包
  • 重庆网站建设重庆网站制作出售自己的网站
  • 郑州建设企业网站找哪个公司网站程序如何制作
  • 普陀网站开发培训学校网站建设 投资合作
  • 商用网站开发计划书正规seo多少钱
  • 献县网站建设公司王也天演过的电视剧
  • 湘潭做网站价格咨询磐石网络从零开始建网站
  • 淘宝联盟自己做网站php网站权限设置
  • 东莞做网站 南城信科wordpress接入官方号
  • 视频网站 wordpress主题自己公司内网网站和外网怎么做同步
  • 网站怎么做图片动态图片不显示不出来的做网站应该了解什么软件
  • 腾讯专门做数据标注的网站是珠海网站建设优化推广
  • 设计师网站源码seo是如何优化
  • 网站跳出率多少合适选择郑州网站建设
  • 网站设计公司 推荐阿里云建设wordpress
  • 网站开发项目标书外贸经济平台代销到哪里买
  • 网站设置方案行业网站建设蓝云
  • 网站地图提交西安知名网络推广公司
  • wordpress电影站模版安卓开发平台
  • 网站seo关键词排名推广免费的域名解析
  • 珠海建站软件抖音推广怎么收费
  • 好发信息网-网站建设室内设计公司经营范围
  • 网站功能模块有哪些做英文网站可以申请补贴吗
  • 大通证券手机版下载官方网站下载wordpress插件图片无法加载
  • wordpress 内外网太原网站推广优化