huangfu Blog
Love Leanote!
Toggle navigation
huangfu Blog
主页
About Me
归档
标签
02函数重载/哑元/参数默认值/内联/动态分配内存/引用
2017-02-06 19:59:43
105
0
0
tarena
#函数重载 **1.概念** 在`同一作用域`中`函数名相同参数列表不同`的函数构成重载关系,注意返回值不包含于参数列表 参数列表不同: * 参数个数 * 参数类型 * 参数顺序 **2.例子代码** #include <iostream> using namespace std; /* 以下三个函数可以构成重载关系*/ int getmax(int x,int y) { cout << "getmax(int,int)" << endl; return x > y ? x : y; } double getmax(int x,double y) { cout << "getmax(int,double)" << endl; return x > y ? x : y; } double getmax(double x,int y) { cout << "getmax(double,int)" << endl; return x > y ? x : y; } int main() { getmax(1,2); // 调用第一个 getmax(1.5,2); // 调用第二个 getmax(1,2.0); // 调用第三个 /* 编译错误*/ //getmax(1.4,1.2); /* 函数指针会根据指针的类型,自动选择相应的函数*/ double (*pgetmax) (int, double); pgetmax = getmax; pgetmax(1, 2.0); } **3. 重载的本质(原理)** C++语言底层调用函数时,不单要考虑函数名,还要考虑参数列表,而C语言只考虑函数名.所以C++函数可以重载,而C语言不同. **4. 重载引入的问题及解决方法** * 问题 跨编译器调用问题, * 解决方法 使用extern "C" 指定函数 按照C语言的方式来生成调用函数名 extern "C" int getmax(int x, int y); 或 extern "C" { int getmax(int x,int y); } 例子代码 Cfunction: #include <stdio.h> int getmax(int x, int y) { printf("this is C function\n"); return x > y ? x : y; } CPPfunction: #include <iostream> using namespace std; /* 按照C语言的方式来生成调用函数名(C为大写)*/ extern "C" int getmax(int x, int y); int main() { getmax(1,2); } #函数参数之哑元 **1. 概念** 如果一个函数的参数 只有参数类型 没有参数名,则这个参数称为哑元 **2. 作用** * 让无参的参数列表严格匹配 `void foo(void);` * 保持函数的向前兼容 `const char* encode(const char* msg, int key); const char* dncode(const char* msg, int key);` `const char* encode(const char* msg, int key); const char* dncode(const char* msg, int);` * 区分成员函数 `/* 前加加*/ operator++() { } /* 后加加*/ operator++(int) { }` #函数参数的默认值 **1. 概念** 定义或声明一个函数时,可以给这个函数的参数指定一个初始值. 调用这个函数的时候,如果不给这个参数传入值则使用默认值,如果给这个参数传入值则会替代掉默认值. **2. 参考代码** #include <iostream> using namespace std; int getmax(int x = 10, int y = 100) { return x > y ? x : y; } int main() { cout << getmax() << endl; // 100 cout << getmax(200) << endl; // 200 cout << getmax(100, 200) << endl; // 200 } **3. 参数默认值使用注意事项** * 函数参数的默认值必须遵循*靠右原则* (一个参数有默认值,则右测所有参数都必须有默认值) `into getmax (int x = 10, int y){} // 错误` * 不要和重载形成调用冲突 `getmax(int x, int y = 200); getmax(int x, int y, int z = 0);` * 当函数的声明和实现分开时,需要在声明中指定默认值实现中不要再指定默认值,否则报错 `int getmax(int x = 10, int y = 100); int getmax(int x,int y) { return x > y ? x : y; }` #内联函数 inline **1. 概念** 在编译时*请求*编译器把函数的代码复制到调用位置. 请求成功,就使用空间换取时间 请求不成功,则成为普通函数调用 **2. 内联函数注意的问题** * 小函数,频繁调用适合内联 * 大函数,稀少调用不适合内联 * 递归函数无法实现内联 * 内联只是个请求,成功就复制代码,不成功就是普通调用 * `定义`在类内的成员函数 默认是内联的 #C++中的动态内存分配 **1. 分配单个变量对应的内存** `类型 *指针名 = new 类型名; 类型 *指针名 = new 类型名(); // 一些编译器会初始化成0 类型 *指针名 = new 类型名(值); // 编译器会初始化成对应值` `delete 指针名; // 释放动态内存` **2. 分配多个变量对应的内存** `类型 *指针名 = new 类型[n];` `delete[] 指针名; // 释放多个变量对应的内存` **3. 例子代码** #include <iostream> using namespace std; int main() { /* 分配单个变量对应内存*/ int *pa = new int; // 垃圾值 int *pb = new int(); // 有可能会初始化成0 int *pc = new int(10); // 一定会初始化成0 /* 分配多个变量对应内存*/ int *pd = new int[10]; /* 释放对应内存空间(单个变量)*/ delete pa; delete pb; delete pc; /* 释放对应内存空间(多个变量)*/ delete[] pd; /* 良好编程习惯*/ pa = NULL; pb = NULL; pc = NULL; pd = NULL; } **4. 定位内存分配** int main() { char data[100]; int *pdata = new (data)int[25];// 在栈区数组所在对应内存中动态分配内存 /* 在栈区分配对应内存的优点是不用手动释放*/ } #引用 **1. 概念** 引用就是一个变量的别名 **2. 语法** int main() { int x; int& rx = x; } * 引用必须初始化 * 引用一旦初始化后,在其生命期内对象不可更改 **3. 引用的应用** * 引用类型的参数 值传递: 1.普通值 2.地址值 引用传递: 参数的类型是引用类型 例子代码 #include <iostream> using namespace std; void myswap(int *a, int *b) { int temp = *a; *a = *b; *b = temp; } void myswap2(int& a, int& b) { int temp = a; a = b; b = temp; } int main() { int x = 1, y = 2; myswap(&x, &y); cout << x << '/' << y << endl; myswap2(x, y); cout << x << '/' << y << endl; } * const引用 如果函数内部不对数据进行修改,则建议对参数写成const引用 这样除了防止修改,还会增强函数的兼容性 例子代码 #include <iostream> using namespace std; void printNum(const int& num) { cout << num << endl; } int main() { int a = 10; const int b = 20; printNum(a); printNum(10); // 如果参数不是const引用编译过不去 printNum(b); // 如果参数不是const引用编译过不去 } * 引用类型的返回值 函数的返回值一般用来做右值,如果希望做左值可以使用指针或引用 `注意:不要返回局部变量的引用` 例子代码 #include <iostream> using namespace std; int* getmax(int* x, int* y) { return *x > *y ? x : y; } int& getmax2(int& x, int& y) { return x > y ? x : y; } int main() { int z = 100; int x = 10; int y = 20; *getmax(&x, &y) = z; cout << y << endl; // 输出100 getmax2(x,y) = z; cout << y << endl; // 输出100 } * 总结 C++中的引用作为函数参数及返回值时,可以做到C语言中一级指针相同的效果及作用. **4. 引用底层是如何实现的?** 引用的指针是用指针实现的,它的本质还是指针 * const 和 * 的问题 `/* 不能通过pi修改对应的内存中的值,也就是指针指向的值是常量*/ const int * pi; int const * pi; /* pi的指向不能改变,也就是该指针是个常量*/ int * const pi;` * 本质 `int& rx = y; 本质是 int * const rx = &y;` **5. 引用和指针的联系与区别** * 联系 引用在底层是用指针实现的`类型 *const r` 指针的很多功能都可以用引用来完成 1. 指针的的参数可以用引用代替 2. 指针类型的返回值可以用引用替代 * 区别 1. 引用必须初始化,指针可以不初始化,因此如果一个类中声明了引用类型,必须在初始化列表初始化 2. 引用一旦初始化,在引用的生命期内就不能改变引用的指向,而指针可以 3. 指针是实体变量,大小是4,而引用是一个别名,不占内存空间,`sizeof引用是求对应类型的大小,而不是求引用的大小` 4. 有二级指针,但没有二级引用 5. 没有引用的指针,如`int&* a; //错误` 但有指针的引用,它相当于二级指针,如`int*& a; // 正确` 6. 有指针的数组,但没有引用的数组 7. 有数组的引用,它相当于指针的引用(二级指针)`int data[3] ----> int (&rdata)[3]` Code #include <iostream> using namespace std; void printArr(int (&data)[3]) { cout << sizeof data << endl; // 12 } int main() { int data[3] = {5,1,2}; printArr(data); }
上一篇:
01名字空间\结构\联合\枚举\布尔
下一篇:
03类型转换运算符/类和对象
0
赞
105 人读过
新浪微博
微信
腾讯微博
QQ空间
人人网
提交评论
立即登录
, 发表评论.
没有帐号?
立即注册
0
条评论
More...
文档导航
没有帐号? 立即注册