4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)
本章主要内容:
- 1)函数重载
- 2)C++调用C代码
- 3)new/delete关键字实现动态内存分配
- 4)namespace命名空间
大家都知道,在生活中,动词和不同的名词搭配一起,意义都会大有不同,比如”玩”:
- 玩游戏
- 玩卡牌
- 玩足球
所以在C++中,便出现了函数重载(JAVA,c#等语言都有函数重载)
1.函数重载(overload)
表示有多个相同的函数名(类似上面的”玩”),但是参数表不同(类似上面的名词)
参数表不同主要有以下几种
- 1) 参数个数不同
- 2) 参数类型不同
- 3) 参数顺序不同
1.1举个栗子
#include <stdio.h> int func(char *str) //func1
{
printf("str=%s\n",str);
} int func(int a) //func2
{
printf("a=%d\n",a);
} int func(int a,int b) //func3
{
printf("a*b =%d\n",a*b);
} int main()
{
char s[]="hello"; func(s);
func();
func(,);
}
输出结果:
str=hello
a=
a*b =
通过上个栗子可以看到,函数名相同,参数不同,而意义却大有不同.
1.2那这些重载函数的入口地址是否相同
修改上面栗子的main()函数,如下图所示:

可以看到输出结果,每个函数的入口地址都不一样(重载函数的入口地址,必须使用强制转换来获取)
也可以通过nm命令来查看符号表,如下图所示:

注意:
- 重载函数需要避免使用参数默认值
- 调用重载函数时,只会匹配函数参数表,与函数返回值无关
- 函数重载必须发生在同一个作用域中
- 重载函数的入口地址,不能直接通过函数名来获取
2.C++与C代码相互调用
当C++想调用C里的某个函数时,则使用extern “C”
还是举个栗子,通过C++调用C里面的add()函数
1) 首先创建3个文件

add.c代码如下:
#include "add.h" int add(int a,int b)
{
return a+b;
}
add.h代码如下:
int add(int a,int b);
main.cpp代码如下:
#include <stdio.h> #ifdef __cplusplus
extern "C" //通过C方式来编译add.h,也就是add()函数
{
#include "add.h"
}
#endif int main()
{
printf("%d \n",add(,));
return ;
}
main.cpp里的__cplusplus宏是C++编译器自带的,而extern "C"只有C++里才有定义.
所以通过__cplusplus宏判断,可以使main.cpp在C或C++编译器下都能编译运行.
2)编译运行:
gcc -c add.c //生成add.o文件
g++ -o main main.cpp add.o //生成main可执行文件
./main
3)输出结果:

3. C++中的动态内存分配
3.1 回顾C:
在C语言中,大家都知道使用malloc()和free(),比如:
int *p = malloc(*sizeof(int)); //申请10个int型空间
if(p)
{
... ...
free(p);
}
从上面栗子,可以看到C是通过库函数完成内存分配的
3.2而在C++中,则通过new关键字进行内存申请,delete关键字进行内存释放,比如:

- Type: 指数据类型,比如int,char,float等
- N: 指申请的数组个数大小
除了上图例子外,new关键字还可以通过分配并初始化(类似calloc()函数)
例如:
int *p1= new int(); //动态分配一个int空间给p1,并赋值为1
float *p2=new float(2.0f); //2.0后面加f,表示2.0是个float类型
char *p3=new char('c');
注意:
- 释放数组的空间时,必须使用delete[],而不是delete,避免内存泄漏
- 使用new时,默认值为随机值,而对于new()时,则为0,比如: int *p = new int(); //默认值为0
3.3 以string为例,创建string数组
#include <iostream>
#include <string>
using namespace std; int main()
{
string *p = new string[]; for(int i=;i<;i++)
p[i] = ""; for(int i=;i<;i++)
cout<<p[i]<<endl; delete[] p;
}
3.3 二维指针示例
以string二维指针为例:
#include <iostream>
#include <string>
using namespace std; int main()
{
string **p = new string*[]; //创建行数 for(int i=;i<;i++)
p[i] = new string[]; //创建列数 for(int i=;i<;i++)
for(int j=;j<;j++)
{
p[i][j]=""; cout<<p[i][j] <<endl;
} for(int i=;i<;i++)
delete[] p[i] ; delete[] p;
}
4.C++中的命名空间(namespace)
4.1回顾C:
大家都知道,在C语言中,当编译多个C文件时,可能会遇到同名全局标识符的错误,这是因为C语言中的所有全局标识符都是共享同一个作用域
4.2所以C++中便提出命名空间(namespace)的概念
- 命名空间会将全局作用域分成不同部分的命令空间,可以将类,对象,函数等聚集在一个namespace里
- 不同命名空间中的标识符可以同名
- 命名空间可以相互嵌套,也就是说A命令空间里可以再次定义B命令空间
- 在C++中,全局作用域也叫默认命名空间
4.3命名空间(namespace)的使用
1)定义一个命名空间:
namespace name //定义一个命名空间,名为name
{
int varialbe;
//... ...
}
2)使用整个命名空间name,并将该空间设为当前默认命名空间:
using namespace name;
3)使用全局命名空间中的变量:
::varialbe; //由于::前面没有命名空间名字,所以使用全局变量
4)使用某个命名空间中的变量:
using name::variable //使用name空间里的variable变量
4.4 举个栗子
#include <stdio.h> namespace First //定义First命名空间
{
int i = ;
} namespace Second //定义Second命名空间
{
int i = 1;namespace Internal //在Second里,再次定义一个Internal空间(实现嵌套)
{
struct Position
{
int x;
int y;
};
}
} int main()
{
using namespace First; //使用First整个命名空间,成为该main()的默认空间
using Second::Internal::Position; //使用Second->Internal空间里的Position结构体 printf("First::i = %d\n", i); printf("Second::i = %d\n", Second::i); Position p = {, };
printf("p.x = %d\n", p.x);
printf("p.y = %d\n", p.y); return ;
}
输出结果:
First::i =
Second::i =
p.x =
p.y =
下章接着来学习: 5.C++里的4种新型类型转换
4.C++中的函数重载,C++调用C代码,new/delete关键字,namespace(命名空间)的更多相关文章
- c++程序设计中的函数重载
函数重载的意思是在一个作用域内(命名空间内)定义了某个或某些具有相同名称的函数,但是他们的参数列表和定义(实现)不相同,如果相同的话,就没啥意义了.当调用一个重载函数时,编译器会通过所使用的参数类型. ...
- 关于在C#中对函数重载理解
函数重载是个什么概念,才接触的这个概念的时候我也是完全昏了,还在自己看看了书后就理解了.那什么是函数重载呢?我个人理解的是在同一个作用域下有多个同名的函数,但是他们的形参的类型是不同的,或者参数个数是 ...
- js中的函数重载
函数重载与js 什么是函数重载 重载函数是函数的一种特殊情况,为方便使用,C++允许在同一范围中声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数.类型或者顺序)必须不同,也就是说用 ...
- c++中的函数重载、函数重写、函数重定义
目录 一.函数重载 二.函数重写 三.函数重定义 为了更加深刻的理解 函数重载.重写.重定义,我们可以带着如下这两个问题去思考: 1.子类中是否可以定义父类中的同名成员?为什么? 可以,因为子类与父类 ...
- C++解析(16):友元与类中的函数重载
0.目录 1.友元的尴尬能力 2.类中的函数重载 3.小结 1.友元的尴尬能力 什么是友元? 友元是C++中的一种关系 友元关系发生在函数与类之间或者类与类之间 友元关系是单项的,不能传递 友元的用法 ...
- 《挑战30天C++入门极限》新手入门:C++中的函数重载
新手入门:C++中的函数重载 函数重载是用来iostream> using namespace std; int test(int a,int b); float test(flo ...
- PHP中实现函数重载
转载自:http://cnn237111.blog.51cto.com/2359144/1284085 由于PHP是弱类型语言,因此函数的输入参数类型无法确定(可以使用类型暗示,但是类型暗示无法用在诸 ...
- C++类中的函数重载
1,本课程最初阶段就学习了函数重载,但是那时研究目标仅限于全局函数,到目前 为止我们学习了三种函数: 1,全局函数: 2,普通成员函数: 3,静态成员函数: 这三种不同类型的函数之间是否可以构成重载, ...
- 从两个角度理解为什么 JS 中没有函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数.类型.顺序)的函数,这组函数被称为重载函数.重载函数通常用来声明一组功能相似的函数,这样做减少了函数名的数量,避免了名字空 ...
随机推荐
- java的finalize()方法与C++的析构函数
---<java编程思想> 读书笔记 --- 2017/3/15 读<java编程思想>读到初始化与清理一章,文中提及java的finalize()方法,联想到了C++的析构函 ...
- Video Target Tracking Based on Online Learning—深度学习在目标跟踪中的应用
摘要 近年来,深度学习方法在物体跟踪领域有不少成功应用,并逐渐在性能上超越传统方法.本文先对现有基于深度学习的目标跟踪算法进行了分类梳理,后续会分篇对各个算法进行详细描述. 看上方给出的3张图片,它们 ...
- DFS算法(——模板习题与总结)
首先,需要说明的是搜索算法本质上也是枚举的一种,时间复杂度还是很高的,遇到问题(特别是有水平的比赛上),不要优先使用搜索算法. 这里总结一下DFS算法: 1.从图中某个顶点出发,访问v. 2.找出刚访 ...
- 把VueThink整合到已有ThinkPHP 5.0项目中
享 关键字: VueThink ThinkPHP5.0 Vue2.x TP5 管理后台扩展 VueThink初认识 VueThink,是一个很不错的技术框架,由广州洪睿科技的技术团队2016年研发( ...
- redis常见使用场景下PHP实现
基于redis字符串string类型的简单缓存实现 <?php //简单字符串缓存 $redis = new \Redis(); $redis->connect('127.0.0.1',6 ...
- 版本控制——TortoiseSVN (1)安装与配置
=================================版权声明================================= 版权声明:原创文章 禁止转载 请通过右侧公告中的“联系邮 ...
- 注释中不允许出现字符串 "--"。
问题: 在启动tomcat时会出现如上错误,同时有可能会出现xml无法解析等错误 解决办法: 注释中不能出现字符串 "--",即需要把xml文件中多余的“--”去掉,例如: < ...
- maven项目生成war包
配置 你的pom.xml文件,在你的overview视窗里 配置 packaging为 war 然后添加 <plugin> <groupId>org.apache.maven. ...
- Centos7-两台Centos机器间复制文件
我又两台Centos机器,一台192.168.1.1:另一台192.168.1.2 现在在将192.168.1.1上的一个文件复制到192.168.1.2.登陆到192.168.1.1然后运行命令 命 ...
- Servlet--超链接,表单提交,重定向,转发4种情况的路径
实际编码中我们经常写路径,写路径既可以写相对路径,也可以写绝对路径.我2年以前我就养成了习惯,只要是写路径我从来都是写绝对路径,因为万一将来我们的项目的目录发生变化,原来要是写相对路径的话就会有路径依 ...