C和C++区别
封装性:
自动性:编译期会自己实现很多东西
1.函数的区别:
函数的默认值参数:
===>形参带默认值的函数
1.给默认值的时候,从右向左给
2.调用效率的问题I
3.定义出可以给形参默认值,声明也可以给形参默认值
4 .形参给默认值的时候,不管是定义处给,还是声明处给,形参默认值只能出现一次
-
常见错误:
但是对于vs2015错误一是可以编译通过的
-
错误四:多文件中函数默认值参数在其他文件中看不到,因此,需要重新赋值
2.内联函数
函数调用的地方,编译器将函数代码按逻辑展开
编译器做的所有事情都是在生成指令时完成的。展开不是指展开代码,而是生成相应的逻辑指令
为什么需要使用内联函数
函数调用的真正目的是为了执行函数体,但是执行函数体之前或之后都需要大量的准备工作。因此对于大体量的函数体可以按照函数的调用规则,但是对于小体量的函数,执行函数调用规则就很不划算,因此使用内联函数让函数在调用点展开,可以大大缩短调用时间,增大执行效率
且没有栈帧开辟,可以减少内存消耗
递归函数不能成为内联函数
原因:
代码到最终的可执行文件经过:预编译,编译,链接这三个大的时期。内联函数代码展开是在编译时期的时候生成的指令在调用点展开的。递归函数必须有一个递归终止条件,并且递归终止条件一定是使用变量进行控制的(若使用常量进行控制要么无法递归,要么无法终止)而且编译器函数展开时无法拿到变量的值。
3.函数的重载
返回值相同,函数名相同,参数列表不同的函数构成重载
当调用函数重载时,代码写了之后是不能确定要调用哪一个函数的,只有在编译期的时候根据其参数的数据类型确定调用哪一个函数。对于这种前期不确定的方式称之为多态
函数的重载属于静多态:编译时期的多态(早绑定),编译时期才真正的决定要调用哪一个
C++可以进行函数重载的原因
数据类型自动转换的默认顺序
double转给其他类型时都是平级
快速记忆:
4.C和C++的相互调用
C++调用C
C++产生函数符号:函数名+参数列表
C参数函数符号:函数名
extern " C "
{
}
C调用C++
1.将C++的函数符号改变成C的函数符号:需要改变C++源文件(不现实)
2.添加一个自己实现的C++文件,自己实现的C++函数作为中间层去调用需要的C++函数,然后让自己实现的C++函数产生C语言符号,之后使用C语言进行调用
5.namespace
目的:进行命名的隔离,防止命名冲突。相当于在一个独立的空间封装了一套命名,用户需要使用的时候再进行引用,不使用时该空间里面的元素和其他人没有任何关系。因此就可以大量防止命名冲突。
6.指针和数组名的区别----什么是指针
示例一:
总结:
数组名-------是地址--------常量-----不能修改值
指针----------是变量,有类型----------可以修改值
指针-----存放地址
指针解引用可以访问存放的数据
地址解引用也可以访问存放的数据
常量与变量的区别:
到变量中去拿值都是对变量地址进行解引用
7.const
C语言无法定义常量,使用const定义的常量叫做常变量
常变量具有常属性,不能作为左值。但是编译器取值时会按照变量的方法,对其地址进行解引用,取出内存中的值。因此叫做常变量。
.c文件
.cpp文件
1.C++中常量就是常量,const 修饰的变量使用常量进行初始化后就是常量,不能进行修改,而使用指针对其进行修改的都是修改的临时变量的值。常量在编译期就直接将常量的数值写在了常量的使用点。
2.const 修饰的常量必须进行初始化。
原因:编译期就会将常量的值写入常量的使用点,除此时间就不能对其进行赋值了。不能对其进行赋值,则该常量就无法使用。常量一旦进行赋值(初始化)后期就无法对其进行改变,因为后期所有使用到该常量的地方都会被替换成数值,即便是指针对其进行修改,也修改的仅仅是生成了临时变量。
3.如果使用变量给const修饰的量进行初始化,则该量会退化成常变量(和C语言中一致)
因此变量想要真正变成常量
1:加const
2:使用常量进行初始化
const 定义的常量占内存
限定作用
8.const与函数参数
9.引用
const和引用都必须进行初始化,而且一旦初始化后期都无法改变,因为编译期都会自动替换
引用的工作原理:
常引用
10.动态内存管理
C语言:malloc free
C++: new delete
11.封装的区别
class的默认权限是private
struct的默认权限是public
12.初始化列表
类中所有的普通成员变量都会在初始化列表进行初始化
不写不代表没有,类似于定义int a;此时a所在的内存空间是有初始值的,是系统默认的值,类似于cdcdcdcd。相当于调用默认的构造函数
int a=int();
一旦构造函数开始执行,所有的成员变量都属于赋值。构造函数之前才属于初始化
const修饰的成员属性和引用必须放在初始化列表
13.static
单例模式
要点:
- 构造函数放在私有里面
- 提供一个静态的接口去调用构造函数获取对象
要求:限制只能产生一个对象,在项目任意地方都可以获取到这个唯一对象
//要求:限制只能产生一个对象,在项目任意地方都可以获取到这个唯一对象
class Only
{
public:
static Only* get_Only()
/*给外界提供一个成员方法,使之可以调用构造函数获取一个对象。
但是这是一个普通的成员方法,由于普通的成员方法调用必须依赖this指针,
而this指针从对象来,外界此时又构造不了对象,
所以该成员方法不能依赖this指针,故定义为静态函数
*/
{
if (NULL == _only)//避免每一次进来都加锁,提升效率
{
_lock.lock();
if (NULL == _only)//确保只构造一个对象
{
_only = new Only();
}
_lock.unlock();
}
return _only;
}
private:
Only();//要调用构造函数就会重新构造对象,因此要想只产生一个对象,外部就不能随意调用构造函数
static mutex _lock;
static Only* _only;
};
Only* Only::_only = NULL;
mutex Only::_lock = mutex();