函数重载&缺省值
函数重载
同名函数有多个不同函数来实现
- 编译器通过输入值来决定所调用的函数,必须保证至少一个函数参数类型不同,其余不能作为区分标志;
- 函数重载时,会优先调用类型匹配的函数实现,不存在时会进行类型转换
函数参数的缺省值
函数定义时设置默认值就是缺省值,在实参缺少时,编译会自动设置为default值
- 有缺省值的函数参数,必须排在没有缺省值参数的后面
1
void print(char* name,int score,char* msg="pass")
- 缺省值可能会导致函数调用二义性,造成冲突。此时编译器会拒绝代码:
1
2
3
4
5
6
7
8void fun(int a, int b=1) {
cout << a + b << endl;
}
void fun(int a) {
cout << a << endl;
}
//测试代码
fun(2);//编译器不知道该调用第一个还是第二个函数
auto+deltype
auto
std=c++11编译,由编译器根据上下文自动确定变量的类型:
1 | auto x = 1; |
- 跟踪返回类型的函数:可以将函数返回类型的声明信息放到函数参数列表的后边进行声明,追踪返回类型在原本函数返回值的位置使用auto:
1
auto func(char* ptr,int val) -> int;
- 使用注意:
- 必须可以在编译期确定其类型
- 变量定义时必须初始化,两种错误如下:
1
2auto a; //错误
auto b4 = 10, b5 = 20.0, b6 = 'a';//错误,没有推导为同一类型 - 函数形参不能被声明为auto
- auto并不是一个真正的类型,因此不能使用以类型为操作数的操作符
- 代替冗长复杂、变量使用范围专一的变量声明,尤其是在循环中
- 定义模板函数时,用于声明依赖模板参数的变量类型。比如说函数A的两个特殊参数会传至模板参数B,B中对于形参的计算中所用到的中间参数或者结果等可以使用auto来定义,就使得模板参数可以在函数重载时具有普适性。同时也可以自动追踪返回类型。
decltype
可以对变量或表达式结果的类型进行推导,decltype(var)
返回的是var的类型:
1 | struct { char name[17]; } anon_u; |
auto+deltype
自动追踪返回类型
- C++11中推导返回类型
1
2auto func(int x, int y) -> decltype(x+y)
{return x+y;} - C++14中返回类型可以不显式指定
1
2auto func(int x, int y)
{return x+y;}
基础知识
内存申请与释放
new
&delete
:指针变量所指内存的动态生成和删除:1
2
3int * ptr = new int(10); // 单个变量
int * array = new int[10]; // 10元素数组
delete ptr; // 删除指针变量所指单个内存单元delete[] array; // 删除多个单元组成的内存
零指针
0
、NULL
、nullptr
0
与NULL
可以说是等价的,当int和ptr产生函数重载时的冲突时需要使用nullptr
,这是一个严格意义上的空指针
基于范围的for循环
在循环头的圆括号中,由冒号”:”分为两部分,第一部分是用于迭代的变量,第二部分则表示将被迭代的范围。常见于容器的元素循环。
1 | #include <iostream> |
类与对象
基本语法
在头文件中声明类
1 | // matrix.h |
成员变量与成员函数
通常,类的声明放在头文件中,而类的成员函数实现/定义放在实现文件中
- 为了便于管理和复用,一般将不同的类分别保存为不同的头文件和实现文件
成员函数的两种定义方式
为了方便解决依赖关系,复杂的成员函数声明和定义一般是分离的,不适用类内定义
- 类内定义
1
2
3
4
5
6class Matrix {
public:
void fill(char dir) {
...; //在类内定义成员函数
}
...}; - 类外定义
1
2
3
4
5// matrix.cpp
#include "matrix.h"
void Matrix::fill(char dir) //类外需要类名限定
{
...// 函数实现}
类成员的访问权限:private
& public
类的成员(包括数据、函数)可以根据需要分成组,不同组设置不同的访问权限
public
修饰的成员可以在类外访问private
默认权限,不允许在类外访问class
中成员的缺省属性为private,因而以下代码中data是默认权限:1
2
3
4
5class Matrix{
int data;
public:
void fill(char dir)
}
protected
用户定义类型:类class
- 对象:用类定义的变量
对象名.成员名
or对象指针->成员名
使用数据成员/函数,类外使用仅能访问public
this
指针
所有成员函数的参数中,隐含着一个指向当前对象的指针变量,这也是成员函数与普通函数的重要区别。可以用作前“对象指针”访问/赋值
内联函数inline
函数调用需要压栈、跳转、退栈、返回,是一个比较慢的过程,大量调用函数会拖慢程序
- 内联函数可以执行类型检查,进行编译器错误检查
- 可以调试
- debug版本没有真正内联,等同于一般函数,因而可以被调试
- release版本实现内联,增加执行效率
- 内联函数生成的是和函数等价的表达式。
使用注意事项
- 避免大段代码使用(相当于把所有调用处copy一遍)
- 避免循环与复杂控制函数:优化问题
- 避免声明与定义分离:编译时需要得到实现,需要写在同文件
- 类声明中定义的函数认为是内联函数:构造函数、析构函数
- 是建议
- 编译器可以拒绝不值得内联的请求(忽略内联修饰符)
- 会选择短小却没有内联修饰符的函数自行判断是否转化为内联函数