(1)内联函数
(2)内联函数与带参宏区别
(3)新的类型转换运算符
const_cast<T>(expr)
static_cast<T>(expr)
reinterpret_cast<T>(expr)
dynamic_cast<T>(expr)
1、内联函数
¥当程序执行函数调用时,系统要建立栈空间,保护现场,传递参数以及控制程序执行的转移等等,这些工作需要系统时间和空间开销。有些情况下,函数本身 功能简单,代码很短,但使用频率却很高,程序频繁调用该函数所花费的时间却很多,从而使得程序执行效率降低。
¥为了提高效率,一个解决办法就是不使用函数,直接将函数的代码嵌入到程序中。但这个方法也有缺点,一是相同代码重复书写,二是程序可读性往往没有使 用函数的好。
¥为了协调好效率和可读性之间的矛盾,C++提供了另一种方法,即定义内联函数,方法是在定义函数时用修饰词inline.
#include <iostream> #include <cstdio> using namespace std; inline int max(int a, int b) { return a > b ? a : b; } #define MAX(a,b) (a) > (b) ? (a) : (b) // 也可以宏实现 int main(void) { int a = 10, b = 20; int c = MAX(a, b); cout << max(a,b) << endl; cout << c << endl; return 0; }
2、内联函数与带参数宏区别
¥内联函数调用时,要求实参和形参的类型一致,另外内联函数会先对实参表达式进行求值,然后传递给形参,而宏调用时只要实参简单地替换形参。
¥内联函数是在编译地时候、在调用的地方将代码展开的,而宏则是在预处理时进行替换的。
¥在C++中建议采用inline函数来替换带参数的宏。
¥C++中推荐常量用 const enum ,带参数的宏(类似于函数调用) 用inline。
3、新的类型转换运算符
¥旧式转型
(T)expr
T(expr)
¥新式转型
const_cast<T>(expr)
用来移除对象的常量性(cast away the constness)。
const_cast 一般用于指针或者引用。
使用const_cast去除const限定的目的不是为了修改它的内容。
使用const_cast去除const限定,通常是为了函数能够接受这个实际参数。
#include <iostream> #include <cstdio> using namespace std; //const_cast用来移除常量的常量性,const_cast一般用于指针或者引用 //这里:使用const_cast去除const限定,通常是为了函数能够接受这个实际参数。 void fun(int& val) { cout << "fun = " << val << endl; //输出:fun = 300 } int main(void) { const int val = 100; //int n = const_cast<int>(val); //错误(活动) E0717 const_cast 中的类型必须是指针、引用或指向对象类型成员的指针 C++教程网 //错误 C2440 “const_cast” : 无法从“const int”转换为“int” C++教程网 //int n = val; //指针 //int* p = &val; // Error,无法从const int* 转换为int* int* p = const_cast<int*>(&val); *p = 200; cout << "val = " << val << endl; //输出:val = 100 cout << &val << endl; //012FF934 cout << p << endl; //012FF934 //引用 const int val2 = 200; int& refval2 = const_cast<int&>(val2); refval2 = 300; cout << "val2 = " << val2 << endl; //输出:val2 = 200 fun(const_cast<int&>(val2)); return 0; }
static_cast<T>(expr)
编译器隐式执行的任何类型转换都可以由static_cast完成
当一个较大的算术类型赋值给较小的类型时,可以用static_cast进行强制转换。
可以将void*指针转换为某一类型的指针。
可以将基类指针指向派生类指针。
无法将const转化为nonconst,这个只有const_cast才可以办得到。
总结:隐式转换--------由编译器自动完成的(一般来说是安全的)如:int a; short b; a = b;
显示转换(强制类型转换)--------如本节所述内容。
#include <iostream> #include <cstdio> using namespace std; int main(void) { int n = static_cast<int>(3.14); cout << "n = " << n << endl; void* p = &n; int* p2 = static_cast<int*>(p); cout << *p2 << endl; return 0; }
reinterpret_cast<T>(expr)
reinterpret_cast"通常为操作数的位模式提供1较低层的重新解释"也就是说将数据以二进制存在形式进行重新解释。
#include <iostream> #include <cstdio> using namespace std; int main(void) { int i; char* p = "This is a example"; i = reinterpret_cast<int>(p);//此时结果,i与p的值是完全相同的。 int* ip; char* pc = reinterpret_cast<char*>(ip); //程序员需要记得pc所指向的真实对象是int型,并非字符串。如果将pc当作字符串指针进行操作,可能会造成运行时错误 //如:int len = strlen(pc); return 0; }
¥尽可能避免使用强制转换(显示类型转换),如果无法避免,推荐使用新式类型转换。
dynamic_cast<T>(expr) (执行“安全向下”转型操作,也就是说支持运行时识别指针或所指向的对象,这是唯一一个无法用旧式语法进行转型操作的)