C++ Primer Note

Posted by Taolee on October 18, 2015

Chapter7 函数

参数传递

1.非引用形参和引用形参

非引用形参调用时,传递给函数体的是实参的局部复制(副本),所以函数体内对形参的修改不影响实参本身的值。 传值调用时不适用的情况有:

  • 函数需要调用大型的对象
  • 有些对象无法复制的情况

所以函数需要操作一个对象时,不要进行非引用调用,可以认为非引用调用得到的是一个ReadOnly的量。引用形参传递给函数的是实参的引用(也就是实参本身),引用形参直接关联到到所绑定的对 象,那么在函数体内对形参的修改实际上就是对实参的修改。以下是引用形参的几个用法:

  1. 使用引用形参返回额外的信息。
    当函数需要返回多个信息时,将存储信息的变量以引用的形式调用。在函数 体内改变变量的值,函数运行结束后,该信息就相当于自动返回了。
  2. 如果引用的唯一目的是避免复制,那么应该使用 const 引用 例如,const int &a
  3. 更灵活的const引用。 应该将不需要修改的引用形参定义为const引用,普通的非const引用形参在调用时不太灵活,这样的形参既不能 使用const对象初始化,也不能使用子面值或者产生右值得表达式初始化。
  4. 传递指向指针的引用。传递的是引用,这个引用本身是指向指针的。换一句话讲,就是传递(存贮指针的内存本身)。与传递其他类型的引用 没有区别。

2.vector和其他类型的容器的形参

一般来讲应该避免值传递容器类型的参数,在C++中,一般使用容器的迭代器作为函数的参数进行传递,以此来访问容器对象。

3.数组形参

由于数组不可以复制,所以一般只能传递数组元素的指针来进行数组的操作调用。当编译器检查 数组形参关联的实参时,它只会检查实参是不是指针,指针的类型和数组的元素类型是否匹配 ,而不会检查数组的长度。一般直接通过值传递数组的名字来进行数组的调用。下面的几个函数的声明是相同的:


void f(int *p){};
void f(int []){};
void f(int [10]){};

通过引用来传递数组的值是安全的。会检查数组本身。

5.有三个编程技巧确保函数的操作不会超越实参数组的边界  

  • 在数组本身存放一个结束的标记。例如C风格的字符串。
  • 使用标准库规范,传递指向数组的第一个元素的指针和指向数组最有一个元素的下一个位置的指针。与标准库风格相同
  • 显示传递表示数组大小的形参

return 语句


要注意的是返回引用的情况。是否安全?返回的引用一定不要是局部变量。因为函数体内声明的 对象会在函数调用结束后进行内存释放。

千万不要返回局部对象的指针。