本章主要内容:

  • 1)函数重载
  • 2)C++调用C代码
  • 3)new/delete关键字实现动态内存分配
  • 4)namespace命名空间

大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比如”玩”:

  • 玩游戏
  • 玩卡牌
  • 玩足球

所以在C++中,便出现了函数重载(JAVA,c#等语言都有函数重载)

1.函数重载(overload)

表示有多个相同的函数名(类似上面的”玩”),但是参数表不同(类似上面的名词)

参数表不同主要有以下几种

  • 1) 参数个数不同
  • 2) 参数类型不同
  • 3) 参数顺序不同

1.1举个栗子

  1. #include <stdio.h>
  2.  
  3. int func(char *str) //func1
  4. {
  5. printf("str=%s\n",str);
  6. }
  7.  
  8. int func(int a) //func2
  9. {
  10. printf("a=%d\n",a);
  11. }
  12.  
  13. int func(int a,int b) //func3
  14. {
  15. printf("a*b =%d\n",a*b);
  16. }
  17.  
  18. int main()
  19. {
  20. char s[]="hello";
  21.  
  22. func(s);
  23. func();
  24. func(,);
  25. }

输出结果:

  1. str=hello
  2. a=
  3. a*b =

通过上个栗子可以看到,函数名相同,参数不同,而意义却大有不同.

1.2那这些重载函数的入口地址是否相同

修改上面栗子的main()函数,如下图所示:

可以看到输出结果,每个函数的入口地址都不一样(重载函数的入口地址,必须使用强制转换来获取)

也可以通过nm命令来查看符号表,如下图所示:

注意:

  • 重载函数需要避免使用参数默认值
  • 调用重载函数时,只会匹配函数参数表,与函数返回值无关
  • 函数重载必须发生在同一个作用域
  • 重载函数的入口地址,不能直接通过函数名来获取

2.C++与C代码相互调用

当C++想调用C里的某个函数时,则使用extern “C”

还是举个栗子,通过C++调用C里面的add()函数

1) 首先创建3个文件

add.c代码如下:

  1. #include "add.h"
  2.  
  3. int add(int a,int b)
  4. {
  5. return a+b;
  6. }

add.h代码如下:

  1. int add(int a,int b);

main.cpp代码如下:

  1. #include <stdio.h>
  2.  
  3. #ifdef __cplusplus
  4. extern "C" //通过C方式来编译add.h,也就是add()函数
  5. {
  6. #include "add.h"
  7. }
  8. #endif
  9.  
  10. int main()
  11. {
  12. printf("%d \n",add(,));
  13. return ;
  14. }

main.cpp里的__cplusplus是C++编译器自带的,而extern "C"只有C++里才有定义.

所以通过__cplusplus宏判断,可以使main.cpp在C或C++编译器下都能编译运行.

2)编译运行:

  1. gcc -c add.c //生成add.o文件
  2. g++ -o main main.cpp add.o //生成main可执行文件
  3. ./main

3)输出结果:

3. C++中的动态内存分配

3.1 回顾C:

在C语言中,大家都知道使用malloc()free(),比如:

  1. int *p = malloc(*sizeof(int)); //申请10个int型空间
  2. if(p)
  3. {
  4. ... ...
  5. free(p);
  6. }

从上面栗子,可以看到C是通过库函数完成内存分配的

3.2而在C++中,则通过new关键字进行内存申请,delete关键字进行内存释放,比如:

  • Type: 指数据类型,比如int,char,float等
  • N:  指申请的数组个数大小

除了上图例子外,new关键字还可以通过分配并初始化(类似calloc()函数)

例如:

  1. int *p1= new int(); //动态分配一个int空间给p1,并赋值为1
  2.  
  3. float *p2=new float(2.0f); //2.0后面加f,表示2.0是个float类型
  4.  
  5. char *p3=new char('c');

注意:

  • 释放数组的空间时,必须使用delete[],而不是delete,避免内存泄漏
  • 使用new时,默认值为随机值,而对于new()时,则为0,比如: int *p = new int();  //默认值为0

3.3 以string为例,创建string数组

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. string *p = new string[];
  8.  
  9. for(int i=;i<;i++)
  10. p[i] = "";
  11.  
  12. for(int i=;i<;i++)
  13. cout<<p[i]<<endl;
  14.  
  15. delete[] p;
  16. }

3.3 二维指针示例

以string二维指针为例:

  1. #include <iostream>
  2. #include <string>
  3. using namespace std;
  4.  
  5. int main()
  6. {
  7. string **p = new string*[]; //创建行数
  8.  
  9. for(int i=;i<;i++)
  10. p[i] = new string[]; //创建列数
  11.  
  12. for(int i=;i<;i++)
  13. for(int j=;j<;j++)
  14. {
  15. p[i][j]="";
  16.  
  17. cout<<p[i][j] <<endl;
  18. }
  19.  
  20. for(int i=;i<;i++)
  21. delete[] p[i] ;
  22.  
  23. delete[] p;
  24. }

4.C++中的命名空间(namespace)

4.1回顾C:

大家都知道,在C语言中,当编译多个C文件时,可能会遇到同名全局标识符的错误,这是因为C语言中的所有全局标识符都是共享同一个作用域

4.2所以C++中便提出命名空间(namespace)的概念

  • 命名空间会将全局作用域分成不同部分的命令空间,可以将类,对象,函数等聚集在一个namespace里
  • 不同命名空间中的标识符可以同名
  • 命名空间可以相互嵌套,也就是说A命令空间里可以再次定义B命令空间
  • 在C++中,全局作用域也叫默认命名空间

4.3命名空间(namespace)的使用

1)定义一个命名空间:

  1. namespace name //定义一个命名空间,名为name
  2. {
  3. int varialbe;
  4. //... ...
  5. }

2)使用整个命名空间name,并将该空间设为当前默认命名空间:

  1. using namespace name;

3)使用全局命名空间中的变量:

  1. ::varialbe; //由于::前面没有命名空间名字,所以使用全局变量

4)使用某个命名空间中的变量:

  1. using name::variable //使用name空间里的variable变量

4.4 举个栗子

  1. #include <stdio.h>
  2.  
  3. namespace First //定义First命名空间
  4. {
  5. int i = ;
  6. }
  7.  
  8. namespace Second //定义Second命名空间
  9. {
  10. int i = 1;namespace Internal //在Second里,再次定义一个Internal空间(实现嵌套)
  11. {
  12. struct Position
  13. {
  14. int x;
  15. int y;
  16. };
  17. }
  18. }
  19.  
  20. int main()
  21. {
  22. using namespace First; //使用First整个命名空间,成为该main()的默认空间
  23. using Second::Internal::Position; //使用Second->Internal空间里的Position结构体
  24.  
  25. printf("First::i = %d\n", i);
  26.  
  27. printf("Second::i = %d\n", Second::i);
  28.  
  29. Position p = {, };
  30. printf("p.x = %d\n", p.x);
  31. printf("p.y = %d\n", p.y);
  32.  
  33. return ;
  34. }

输出结果:

  1. First::i =
  2. Second::i =
  3. p.x =
  4. p.y =

下章接着来学习: 5.C++里的4种新型类型转换

4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)的更多相关文章

  1. c++程序设计中的函数重载

    函数重载的意思是在一个作用域内(命名空间内)定义了某个或某些具有相同名称的函数,但是他们的参数列表和定义(实现)不相同,如果相同的话,就没啥意义了.当调用一个重载函数时,编译器会通过所使用的参数类型. ...

  2. 关于在C#中对函数重载理解

    函数重载是个什么概念,才接触的这个概念的时候我也是完全昏了,还在自己看看了书后就理解了.那什么是函数重载呢?我个人理解的是在同一个作用域下有多个同名的函数,但是他们的形参的类型是不同的,或者参数个数是 ...

  3. js中的函数重载

    函数重载与js 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,也就是说用 ...

  4. c++中的函数重载、函数重写、函数重定义

    目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...

  5. C++解析(16):友元与类中的函数重载

    0.目录 1.友元的尴尬能力 2.类中的函数重载 3.小结 1.友元的尴尬能力 什么是友元? 友元是C++中的一种关系 友元关系发生在函数与类之间或者类与类之间 友元关系是单项的,不能传递 友元的用法 ...

  6. 《挑战30天C++入门极限》新手入门:C++中的函数重载

        新手入门:C++中的函数重载 函数重载是用来iostream>  using namespace std;  int test(int a,int b);  float test(flo ...

  7. PHP中实现函数重载

    转载自:http://cnn237111.blog.51cto.com/2359144/1284085 由于PHP是弱类型语言,因此函数的输入参数类型无法确定(可以使用类型暗示,但是类型暗示无法用在诸 ...

  8. C++类中的函数重载

    1,本课程最初阶段就学习了函数重载,但是那时研究目标仅限于全局函数,到目前 为止我们学习了三种函数: 1,全局函数: 2,普通成员函数: 3,静态成员函数: 这三种不同类型的函数之间是否可以构成重载, ...

  9. 从两个角度理解为什么 JS 中没有函数重载

    函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...

随机推荐

  1. php短信接口代码

    这篇文章主要为大家详细介绍了php短信接口代码,php短信发送.php批量发送.php获取余额等代码,感兴趣的小伙伴们可以参考一下 本文实例为大家分享了几个常用的php短信接口代码,供大家参考,具体内 ...

  2. PHP网站从Apache转移到Nginx后产生404错误的原因和解决办法

    原案例分析: 1.原来的网站在wamp环境下搭建完成,一切正常,上传到虚拟主机环境为lnmp,结果访问时可以打开主页,然后点其他页面全部报404错误: 2.经分析得出原因:原网站环境为wamp使用了伪 ...

  3. 解Linux SSH命令大全,新手必看SSH命令

    下面介绍一些基本的常用的Linux SSH命令,都是一些很简单的Linux SSH命令,新手掌握了这几个,一般管理一般的vps或者linux主机就可以了!     我们的教程介绍了putty的使用方法 ...

  4. Python3 的函数(2)

    1.形参和实参 def MyFun(x): return x ** 3 y = 3 print(MyFun(y)) x为形参,y为实参. 2.函数文档 在函数内用单引号引起来的一段文字,在调用函数时不 ...

  5. 推荐一款强大的3D家装开源软件

    2015年家装o2o着实火了一把.家装涉及到上门量尺,再设计,这个过程是免不了的. 目前基于bs架构的酷家乐,爱福窝等,流行起来就是着力于这点,通过一个点寻找突破口,进入深度挖掘,带动其他家具等产品来 ...

  6. JavaScript Date 时间对象方法

    Date(日期/时间对象) Date 操作日期和时间的对象 Date.getDate( ) 返回一个月中的某一天 Date.getDay( ) 返回一周中的某一天 Date.getFullYear( ...

  7. 智能家居esp8266对接机智云

    依然存在稳定性问题 机智云官网--机智云 一个比较详细的教程--esp8266 一开始采用的是esp12f   可是他太不稳定,总是掉线,机智云的固件我也是刷了无数遍,哎太难了. 我比较懒,走过了太多 ...

  8. linux_vi快捷键

    vi有哪些快捷方式? 到行头: 0 ^ home 到行尾: $ shif+a(编辑模式) end 退出保存: wq . x .wq!(强制退出保存) 强制退出不保存: q! 光标移到文件最后一行: s ...

  9. 自己用的一套reset.css,打算整理一下方便以后用,持续更新中,各位大神,不喜勿喷

    *{margin: 0; padding: 0;border:none;}img{vertical-align: top;width: 100%;border: none;}ul,li{list-st ...

  10. 控制器没有足够的带宽可利用为USB大容量存储设备的解决方法

    伴随网盘时代的没落,最近刚入手了一个移动硬盘.现在的移动硬盘都是USB3.0,传输速度比USB2.0要快很多.但是链接笔记本电脑后发现传输速度在20MB/s左右,跟USB2.0速度差不多,并不能达到传 ...