wenlong1423
7/4/2014 - 8:01 AM

C++ Primer第5版 学习笔记 第六章.md

###C++ Primer第5版 学习笔记

####第六章

  1. 函数实参求值顺序取决于编译器
  2. 列表形参为空,相当于 void
  3. 名字 -> 作用域,对象 -> 生命周期
  4. 只存在于块执行期间的对象称为自动对象,形参是自动对象
  5. 局部静态变量在程序执行路径第一次经过对象定义语句时初始化,直到程序终止才被销毁,内置类型的.如果没有显式初始值,局部静态变量初始化为 0
  6. .obj(Windows) .o(UNIX)含义是文件包含对象代码(object code)
  7. 实参初始化形参时会忽略顶层 const
  8. 尽量使用常量引用,不能把 const 对象,字面值,需要类型转换的对象传递给普通的引用实参
  9. void print(const int*);
    void print(const int[]);
    void print(const int[10]);//10没有意义
    

上面三个等价,编译器只会检测实参是否是(或者能转换为) const int *

  1. C++ 允许将变量定义成数组的引用,形参也可以是数组的引用

    void print(int (&arr)[10]) {
        for (auto elem : arr) {
            cout << elem << endl;
        }
    }
    
不过数组的大小是构成数组类型的一部分,只能将此函数作用于大小为 10 的数组

11. 对同类型可变形参,可以传递 initializer_list 类型,列表中的元素是 const

    ```
    void error_msg(initializer_list<string> li) {
        for (auto beg = li.begin(); beg != li.end(); ++beg) {
            cout << *beg << " ";
        }
        for(auto &i : li) {//因为有 begin 和 end 成员,所以可以使用范围 for 循环
            cout << i << " ";
        }
    }
    error_msg({"function a", "okay"});//调用
    ```
12. 对不同类型的可变形参,可使用可变参数模板
13. 函数如果返回指针,引用,类的对象,就能直接使用函数调用的结果访问结果对象的成员.调用一个返回引用的函数返回左值,其他则返回右值
14. C++11 可以返回花括号包围的值得列表

    ```
    vector <string> process() {
        return {"function a", "okay"};
    }
    ```
如果函数返回类型为内置类型,花括号中只能有一个值,且如果有类型转换,占用空间不能减小。返回类类型,则由类本身定义初始值如何使用(相当于值初始化的花括号形式)
15. 尾置返回类型可用于任何函数,对返回类型比较复杂的函数最有效

    ```
    auto func(int i) -> int(*)[10]//返回值类型为指向含有10个int的数组的指针
    ```
如果知道返回指针指向的数组,也可使用 decltype

    ```
    int odd[] = {1,3,5,7,9};
    int even[] = {0,2,4,6,8};
    decltype(odd) *arrPtr(int i) {
        return (1 % 2) ? &odd : &even;
    }
    ```
16. 形参顶层 const 没有区别,底层 const 与非常量形参可重载,对非常量对象或指向非常量对象的指针,优先使用非常量版本
17. 在不同的作用域中无法重载函数名,名字查找发生在类型检查之前
18. 通常应在函数声明中指定默认形参,并放在头文件中,多次声明同一函数合法
19. 用作默认形参的名字在函数声明所在的作用域进行解析,但求值发生在函数调用时
20. constexpr 函数能用于常量表达式,返回值类型,所有形参的类型都得是字面值类型,函数体中必须有且只有一条 return 语句,constexpr 函数被隐式指定为内联函数
21. 内联函数和 constexpr 函数可以多次定义,但必须完全一致,因此通常定义在头文件中
22. assert(expr),对 expr 求值,为假则输出信息并终止程序,assert 是预处理宏,在定义了 NDENUG 时 assert 才有效
23. 重载函数进行函数匹配时,所有的算数类型转换级别都一样
24. 定义返回函数指针的函数时

    ```
    using F = int(int*, int);
    using FP = int(*)(int *, int);
    FP f1(int);//对,返回类型为指针
    F f1(int);//错,返回类型不能是函数
    F *f1(int);//对,显式指定返回类型为指针
    auto f(int) -> int (*) (int *, int)//返回值为函数指针
    int f(int);
    decltype (f) *getfun(int i);//decltype返回函数类型,而不是指针类型
    ```