-
函数定义
-
参数传递
-
其中引用形参的好处,可以传递大型数组或者类类型,复制实参的话传递小规模类型倒不会影响效率。要避免复制的话,可以用const引用。
-
写程序的时候,应该将不需要修改的引用形参定义为const引用。
-
指向指针的引用。
int* &v1
这里面v1是对指针的引用,也就是说,这样你就可以修改指针的值了,不然的话只能修改指针指着的那个地方的值。其实只要明白一点就好了,指针形参也会进行参数复制的。 -
标准库容器的非引用形参会把容器里的每一个元素都复制一边。
-
编译器忽略为任何数组形参指定长度,比如
void function(const int arr[10])
,是不会理它的长度的,只会识别地址。 -
为了防止数组越界,可以学标准库的思想,传进去两个参数,一个是begin地址一个是end地址。
-
main函数参数: eg.
$./prog -d -o
int main(int argc, char **argv){ ... } argv[0] = "prog"; argv[1] = "-d"; argv[2] = "-o";
-
-
函数的返回值
- 非引用类型,将会复制到临时变量
- 引用类型,将返回自身,没有复制过程
-
函数声明
- 只能定义一次,可以声明多次
- 声明的形参名字虽然可以忽略,但是写的话一般作为辅助文档。
- 在头文件中提供函数声明。
- 默认形参。当函数中一个参数设置了默认值,那么它后面所有的参数都要设置默认值。在函数调用的时候,你提供的参数会覆盖默认形参,而且是从左到右一一对应的覆盖,没有覆盖的就会自动用原来的默认值。因此,设计带有默认实参的函数,你需要排列好形参,使得用的最少的默认实参放在靠前,用的最多的默认实参放在靠后。
- 默认实参可以是任何适当类型的表达式。eg. string func(string height = getHight());
- !!通常,应该在函数声明的文件中指定默认实参,而不是在函数定义的文件中。因为如果在定义中指定,那么只有在包含了这个函数所在源文件的情况下,调用函数才会使默认实参奏效。
-
局部对象
-
内敛函数
- 内敛函数一般是用于那些简单的,只有几句的函数,内敛函数需要在头文件中定义。
- 在头文件中加入或修改 inline 函数时,使用了该头文件的所有源文件都必须重新编译。
-
类成员函数
- bool A::do(int i) const{ return i;} 这样子定义的函数叫做常量成员函数,const改变了隐含的this形参的类型,这里的this是指向const对象的指针,它是这个成员函数的形参,只不过是隐世传进来的。因此这时候this只能用来调用非const成员函数,和只读成员变量。
- 默认构造函数适用于那些只有类类型成员的类,假如有基本类型的话,那最好明确定义类的构造函数。
-
重载函数:就是相同函数名,不同形参列表
-
同一种类型的const形参和非const形参在编译器检查形参列表来判断是重载还是重复声明的时候,视为同一种类型。BUT:仅当形参是引用或指针时,形参是否为 const 才有影响。
-
为了确定最佳匹配,编译器有个匹配规则。。我懒得写了
-
函数重载和作用域
- 一个全局变量或者函数的名字会被局部声明的变量或者函数名字屏蔽掉。所以,因为这个规则的原因,重载函数都要写在同一个作用域里,不然之间可能会被屏蔽。
-
-
指向函数的指针
-
用typedef简化函数指针的定义
typedef bool (*cmpFcn)(const string &, const string &);
这时候要使用该类型函数,只需要直接用cmpFcn就行了。然后你可以这么用
// compares lengths of two strings
bool lengthCompare(const string &, const string &);
cmpFcn pf1 = 0; // ok: unbound pointer to function
cmpFcn pf2 = lengthCompare; // ok: pointer type matches function's type
pf1 = lengthCompare; // ok: pointer type matches function's type
pf2 = pf1; // ok: pointer types match
```-
调用
pf("hi", "bye"); (*pf)("hi", "bye"); //两种都行,前者会隐式转换罢了
-
返回指向函数的指针int
(*ff(int))(int*, int);
,看着很麻烦,拆开看。 -
指向重载函数的指针,就是参数记得要精确匹配。
-