Unit02: 重载与缺省参数 、 内联与动态内存分配 、 引用 、 显式类型转换 、 类和对象

来源:互联网 发布:现实有多残酷知乎 编辑:程序博客网 时间:2024/06/05 14:03

八、 c++ 的函数  

1. 函数重载  eg: 图形库中画图函数  c:     void drawCircle(int x, int y, int r){}    void drawRect(int x, int y, int w, int h){}    ...  c++:    void draw(int x, int y, int r){}    void draw(int x, int y, int w, int h){}    ...  1) 函数重载的定义    在相同作用域中,定义同名的函数, 但是它们的参数有所区别,这样的函数构成重载关系.    注: 重载与函数返回类型无关,与参数名也无关.  2) 函数重载的匹配    调用重载关系的函数时,编译器将根据实参与行参匹配度,自动选择最优的重载版本.    当前编译器(g++ 4.4.7)的一般匹配规则:    完全匹配 > 常量转换 > 升级转换 > 降级转换 > 省略号匹配  3) 重载实现原理    c++ 编译器是通过对函数进行换名, 将参数表的类型信息整合到新的名字中,实现解决函数重载与名字冲突的矛盾.    思考题: extern "C" 声明的作用?2.  c++ 函数的缺省参数    1) 可以为函数的部分或全部行参指定缺省值,调用该函数时,如果不给实参,就取缺省值作为相应的行参的值.    eg:    void func(int a, int flags = 缺省值){}    int main(void){        func(10);        func(10, 20);    }    2) 缺省值必须靠右,如果一个参数带有缺省值,那么这个参数的右侧的所有行参都必须带有缺省值:    eg:    void func(int a = 100, int b = 200, int c){} // Error    void func(int a, int b = 200, int c){} // Error    void func(int a, int b, int c = 300){} // Ok    void func(int a, int b = 200, int c = 300){} // Ok    3) 如果函数的定义和声明分开,缺省参数应该写到函数的声明部分,而定义部分不写,但是最好的注释,提高代码的可读性。    void func(int a = 100) // 函数的声明    void func(int a /*= 100*/){} // 函数的定义3.  c++ 函数的哑元参数    1) 定义: 只有类型没有变量名的行参称为哑元        void func(int /* 哑元参数 */){            // code        }        int main(void){            func(100);        }    2) 为了兼容旧代码        eg:        算法库:         void math_func(int a, int b){            // code        }        使用者:        int main(void){            math_func(10,20);            math_func(20,50);            math_func(30,50);            // ...        }        ------------------------        升级算法库:        void math_func(int a, 哑元){            // ...        }        使用者:        int main(void){            math_func(10,20);            math_func(20, 50);            math_func(30, 50);            // ...        }    3) 运算符重载, 区分前后 ++/-- 4.  内联函数 inline    // 思考题: inline 关键字的作用    八、 4 思考题答案    使用 inline 关键字修饰的函数, 表示这个函数是内联函数, 编译器会尝试做内联优化,避免函数调用的开销.        1) 多次调用的小而简单的函数适合内联        2) 调用次数极少或者大而复杂的函数不适合内联        3) 递归函数不能内联        4) 内联只是一种建议而不是一种强制要求, 能否内联主要取决于编译器,有些函数不加 inline 关键字也会以内联的方式展开,有些函数即便加了 inline 关键字也不会处理为内联。    九、 c++ 的引用 (reference)        1.  定义引用就是给某个变量起别名,对引用的操作与对变量的操作完全相同。        int a = 10;        int &b = a; // 定义引用 b, b 就是 a 的别名        b++;        cout << a << endl; // 11        2.  常引用            1) 定义引用的时候加 const 修饰, 即为常引用, 不能通过常引用修改引用的目标            eg:            int a = 100;            const int& b = a; // b 就是 a 的常引用            b = 20; // Error            2) 普通的引用只能引用左值(变量), 常引用也叫万能引用,既可以引用左值也可以引用右值。            eg:            int &r = 100; // Error            const int& r = 100 // Ok        3.  关于左值和右值的概念            1) 左值: 可以放在赋值运算符的左边,可以被修改, 可以被取地址.            int i;            i = 100;            ++i;            &i;            常见左值:            - 变量            - 前++/-- 表达式的值、赋值表达式的值            eg:            int number = 1;            cout << (++number) << endl; // 2            cout << (number) << endl; // 2            ++number = 10; // Ok            ++++++number;            eg:            int a = 10;            int b = 20;            (a = b) = 30;            cout << a << endl; // 30            cout << b << endl; // 20            2) 右值: 只能放在赋值运算符右边,不可以被修改, 不可以被取地址.            常见右值:            - 字面值                10 = i; // Error                ++10; // Error                &10; // Error            - 大部分表达式的值            eg:            int number = 1;            cout << (number++) << endl; // 1            cout << (number) << endl; // 2            number++ = 20; // Error            number++++; // Error            eg:            int a = 3;            int b = 5;            (a + b) = 10; // Error            - 函数返回值              int func(void){                int a = 100;                return a; // 将 a 保存到一个临时变量中: temp = a              }              int main(void){                int res = func(); // int res = temp                foo() = 200; // Error                ++foo(); // Error              }        4. 引用型的参数            1) 可以将引用用于函数的参数, 可以直接修改实参变量的值, 同时可以减少函数调用的开销:            eg:            void func(int& a = x){                a++;                cout << a << endl; // 2            }            int main(void){                int x = 1;                func(x);                cout << x << endl; // 2                return 0;            }            2) 引用参数有可能意外修改实参变量的值,如果不希望修改实参本身,可以将行参定义为常引用, 在提高传参效率的同时还可以接收常量型的实参。            思考题:            1.  使用引用参数完成两个字符串(char*)的交换            int main(void){                const char* s1 = "hello";                const char* s2 = "world";                swap4(s1, s2);                cout << s1 << endl; // world                cout << s2 << endl; // hello            }            2. 总结引用和指针的区别和联系    八、 1 (3)思考题答案    思考题答案: 函数声明前加入 extern "C"要求 c++ 编译器不对函数做换名,编译 c 程序调用该函数.    注: 这样的函数无法重载    eg:    extern "C" void func(void){// code}    extern "C"{        void func1(){// code}        void func2(){// code}    }
0 1
原创粉丝点击