C++和C++11的一些特性,建议初学者看看
1. 命名空间
-
定义: namespace 空间名 { } 命名空间可以嵌套定义, 如: namespace N1 { int n1; namespace N2 { int n2; } } 使用时也需要嵌套, 例如: N1::n1 = 0; N1::N2::n2 = 0; 编译器会将同名的命名空间合并, 这点和汇编中段的处理类似. 使用时可以使用 using namespace 空间名 的方式将整个空间引入, 也可以使用 using 空间名::成员名 将空间中的某个成员引入.但一般建议使用 空间::成员名 的方式使用, 以防止空间污染.
2. C++输入&输出
-
C++的输入输出使用"流"来实现.与C语言相比, 不需要输入控制字符, 流会根据输入数据的类型自动匹配对应的输出, 但是在某些场景下效率会比printf低很多.
3. 缺省参数
缺省参数是声明或定义函数时为函数的参数指定一个默认值. 在调用该函数时, 如果没有指定实参则采用该默认值, 否则使用指定的实参.
-
半缺省参数必须从右往左依次来给出, 不能间隔着给 缺省参数不能在函数声明和定义中同时出现 缺省值必须是常量或者全局变量
4. 函数重载
在同一作用域中声明几个功能类似的同名函数, 这些同名函数的形参列表(参数个数/类型/顺序)必须不同, 常用来处理实现功能类似数据类型不同的问题. 原因: C++的函数名修饰规则与C不同
-
linux: _Z + 函数名字符个数 + 参数类型简写 VS: ?@命名空间, 类域@函数名 + 参数信息@
5. 引用
引用相当于变量的一个别名, 在底层实现上与指针相同, 只是使用时与指针有所区别.
-
在使用时必须初始化 引用的实体不能变更 没有多级引用 sizeof的大小与引用的实体相同
除此之外, 一些使用指针需要注意的问题使用引用时也需要注意, 例如实体的生命周期.
6. 内联函数
以inline修饰的函数叫做内联函数, 编译时C++编译器会在调用内联函数的地方展开, 没有函数压栈的开销, 在一定程度上可以提升程序运行的效率.
-
inline是一种以空间换时间的做法, 省去调用函数额开销. 所以代码很长或者有循环/递归的函数不适宜使用作为内联函数. inline对于编译器而言只是一个建议, 编译器会自动优化. inline函数的定义声明不能分开, 函数展开后就没有函数地址了, 会导致链接错误.
7. auto关键字(C++11)
C++11中, auto不再是一个存储类型指示符, 而是作为一个新的类型指示符来指示编译器, auto声明的变量必须由编译器在编译时期推导而得. 因此, auto修饰的变量必须是编译器能推导出类型来的, 像是函数的参数, 没有初始化的变量之类, 编译器就无法推导.
8. 基于范围的for循环(C++11)
范围for常和auto搭配使用, 例:
int arr[] = { 1, 2, 3, 4, 5}; for(auto e : arr) { cout << e << endl; }
程序执行时会遍历数组arr.
9. 指针空值—nullptr(C++11)
在C++11中, nullptr作为一个新关键字被引入, 它代表一个指针空值常量. nullptr的类型为nullptr_t, 可以被隐式转化为指针类型.
-
为什么要使用nullptr, 是因为NULL它不香吗?
NULL本质上是一个宏, 在使用时会有一些问题, 例如下面的代码:
void fun(int) { cout << "int_fun" << endl; } void fun(int*) { cout << "int*_fun" << endl; } int main() { fun(0); fun(NULL); fun((int*)NULL); return 0; }
程序fun(NULL)的效果与fun(0)相同, 若要调用参数类型为指针的函数则必须将NULL强转为指针类型, 而使用nullptr则会调用参数为指针类型的函数. 同理, 使用sizeof(NULL)和sizeof(nullptr)的含义也是不一样的, 前者代表 int 0 的大小, 后者代表一个指针类型的大小. 总结: 使用nullptr代码的可读性更好, 健壮性更高