函数指针:
f(g);//传递函数g的地址
f(g());//传递调用函数g的返回值
声明函数指针:
double p(int);
double (*pf)(int);
pf = p;
调用函数指针:
double y = (*pf)(5);//更好,明显指出函数指针
double y = pf(5);//也行
const double * (*p1)(const double *, int);
//函数指针数组,注意[]
const double * (*pa[3])(const double *, int) = {f1, f2, f3};
//*pa[3]是包含3个指针的数组,其他部分指出指针的类型
//调用
const double * px = pa[0](av, 3);
const double * px = (*pa[0])(av, 3);
//pc是指向pa的指针 (*pc) = pa
const double * (*(*pc)[3])(const double *, int);
//调用
(*pd)[0](av,3);
(*(*pd))[0](av,3);
//注意pa和&pa的差别:数字上相同,类型不同
//pa== &pa[0]; &pa是整个数组的地址,&pa+1为pa后12个内存块地址
//**&pa == *pa == pa[0]
typedef const double *(*p_fun)(const double *, int);
p_fun p1 = f
++和+1的区别:++不会改变变量类型,char类型++后还是char
内联函数:在声明或者定义时加上inline关键字 一般省略定义,直接在原型时定义 内联函数不能递归
引用必须在声明时初始化 只能通过初始化声明来设置引用不能通过赋值设置
常量引用:不修改引用值
现在编译器不允许将表达式传递给引用变量,只有引用参数为const则c++将生成临时变量,只要:
- 实参类型正确但不是左值
- 实参类型不正确但可以被转换成正确类型
左值:可被引用的数据对象
非左值:字面常量(字符串除外)包含多项的表达式
double refcube(const double & ra) {
return ra * ra * ra;
}
double side = 3.0;
double * pd = &side;
double & rd =side;
long edge = 5L;
double lens[4] = {2.0,1.0,1.0,1.0};
double c1 = refcube(side);
double c2 = refcube(lens[2]);
double c3 = refcube(rd);
double c4 = refcube(*pd);
double c5 = refcube(edge); //临时引用变量
double c6 = refcube(7.0); //临时引用变量
double c7 = refcube(side + 10.0); //临时引用变量
如果引用非const,不会生成临时变量,方式对其进行修改
尽可能使用const
- 避免无意间修改
- 处理const和非const实参
- 正确生成并使用临时变量
&&:右值引用
可以将函数返回值设置为引用类型,这样一来将值赋值给函数调用也是可行的,
常规返回类型为右值,这种返回值位于临时内存单元中,可能马上就不存在了
如果要返回一个引用类型,又不允许对其进行赋值操作,则加上const
dup = f(a,b);
如果f返回一个结构,会先把这个结构复制一份再返回该拷贝给dup;
如果f返回一个结构引用,则直接赋值给dup
返回引用时,避免返回函数终止时不再存在的内存单元引用,避免返回临时变量,避免返回指向临时变量的指针
如何避免:
-
只是返回作为参数传递给该函数的引用
-
用new来分配新的空间,不过是隐式的用引用的方式 存疑 p268
const free_throws & clone(free_throws & ft) { free_throws * pt; *pt = ft; return *pt; } free_throws & jolly = clone(three);
string类定义了一种char* 到string的转换功能,允许使用c风格字符串来初始化string对象
对于使用传递的值而不修改的函数 :
- 数据对象很小,按值传递
- 数据对象是数组,const指针
- 较大的结构,const引用或者const指针
- 类对象,const引用
对于修改调用函数中数据的函数:
- 是数组,则只能用指针
- 是内置数据类型,则用指针 例外是cin >> n; 使用了引用 而不是cin >> & n;
- 是结构,则使用引用或指针
- 是类对象,则使用引用
对于带参数列表的函数必须从右向左赋值默认值
函数重载时将引用类型和类型本身视为同一种特征标
const变量只有在定义了有和没有const的时候才有效重载,如果没有定义,则有const的版本能接收const和非const变量,没有const的版本只能接受非const变量
void sink(double & r1); //modifiable lvalue
void sank(const double & r2); //modifiable lvalue, const lvalue, rvalue
void sunk(double && r3); //rvalue
//如果都使用,那么将自动调用最匹配的版本:
void staff(double & rs); //m lvalue
void staff(const double & rcs); //c lvalue, rvalue
void stove(double & r1); // m lvalue
void stove(const double & r2); // c lvalue
void stove(double && r3); // rvalue
//如果没有定义stove(double &&),stove(x+y)匹配stove(const double &)
函数重载:函数执行相同任务,但是使用不同类型数据时使用
编译器使用名称修饰/名称矫正来识别重载的函数
c++允许将结构赋值给另一个结构
()