c++11新特性详细解读(未完待续...)
1. 初始化的参数列表
c++98之前可以使用大括号对数组、对象进行初始化操作,例如:
int m_arr[2] = {0};
而在c++11中,扩展可以用大括号用来做统一初始化的范围,可以理解为万物皆可,以下的例子是一个比较常用的场景,省掉了以前c++98智能在构造函数上进行参数初始化的麻烦
#ifndef INITPARAMS_H
#define INITPARAMS_H#include <string>#include "ICPlusPlusTest.h"enum eCCType
{eCCType_None
};typedef struct stStructType
{int value;
} StructType;class CObject
{
public:// c++98初始化参数列表玩法CObject(bool bValue) : m_bValue(bValue) {// c++98初始化参数列表玩法m_bValue = bValue;}private:bool m_bValue;
};class InitParams : public ICPlusPlusTestInterface
{
public:InitParams();void test() override;private:int m_buildinType1 = 1; /// > 内置类型int m_buildinType2 {2}; /// > 内置类型int m_arr[2] = {0}; /// > 数组std::string m_sName {"zhangsan"}; /// > 字符串eCCType m_eType = eCCType_None; /// > 自定义枚举StructType tp {3}; /// > 自定义结构体CObject m_obj {false}; /// > 自定义类
};#endif // INITPARAMS_H
2. nullptr
由于C++98中NULL被定义成字面量0,这样就可能回带来一些问题,因为0既能指针常量,又能表示整形常量。所以出于清晰和安全的角度考虑,C++11中新增了nullptr,用于表示空指针
const char *p = nullptr;
3. 类型推导
这块内容网上很多长篇大论写得非常详细,实际没什么必要,想详细了解的可以参看我的这篇文章:https://blog.csdn.net/SuperYang_/article/details/140574170
这里对重点内容进行说明,类型推导有auto和decltype两种:
3.1 auto
主要用于对变量类型进行推导,例如
auto x = 3.14; // x是浮点型double
auto y = 520; // y是整形int
auto z = 'a'; // z是字符型char
比较实用的几种场景:
1> 用在循环遍历:
map<int, string> person;
// 简化代码(累死的还有用auto来简化一些智能指针相关的类型)
for (auto it = person.begin(); it != person.end(); ++it);
2> 用在泛型编程:
template <class A>
void func(void)
{auto val = A::get(); // 不知道A的get静态方法会返回什么类型,用auto来接cout << "val: " << val << endl;
}
3.2 decltype
用于对表达式类型的推导,例如
int a = 10;
decltype(a) b = 99; // b -> int
说实话上面这种没啥卵用,正常人不会这么写代码,比较实用的是用在泛型编程中,例如:
template <typename T, typename U>
// 返回类型后置语法,无法确定t + u的返回值类型,可以自动推导
auto add(T t, U u) -> decltype(t + u)
{return t + u;
}
4. 智能指针
主要分为auto_prt、unique_ptr、shared_ptr、weak_ptr;auto_ptr存在重大缺陷,现在已经废弃不建议使用了,而unique_ptr与shared_ptr的区别主要在于unique_ptr使用的是控制权转移的方式实现,shared_ptr使用引用计数的方式实现,weak_ptr主要是为了解决shared_ptr的循环引用问题配合shared_ptr使用的,具体可以参考博主的另一篇文章:https://blog.csdn.net/SuperYang_/article/details/141772279
5. Lambda表达式
使用的核心在于理解并掌握其一般使用形式:
[capture clause] (parameters) mutable -> return-type { /* function body */ }
1> [captureclause]:捕捉列表。该列表总是出现在lambda函数的开始位置,编译器根据[]来判断接下来的代码是否为lambda函数,捕捉列表能够捕捉上下文中的变量供lambda函数使用
2> (parameters):参数列表。与普通函数的参数列表一致,如果不需要参数传递,则可以连同()一起省略
3> mutable:默认情况下,lambda函数总是一个const函数,mutable可以取消其常量性。使用该修饰符时,参数列表不可省略(即使参数为空)
4> ->return-type:返回值类型。用追踪返回类型形式声明函数的返回值类型,没有返回值时此部分可以省略。返回值类型明确情况下,也可省略,由编译器对返回类型进行推导
5> {statement}:函数体。在该函数体内,除了可以使用其参数外,还可以使用所有捕获到的变量
更详细的内容参考:https://blog.csdn.net/SuperYang_/article/details/141778639
6. constexpr
constexpr是 C++11 中引入的新的关键字,它最主要的作用就是将一些固定结果的常量表达式、函数、类、结构等相关计算从运行态提前到编译时,极大的提高程序效率;可用于程序性能优化。
比较使用的几种场景:
6.1 用于编译时就确定长度数组
#include <iostream>
#include <array>int main(void)
{constexpr int size = 10;std::array<int, size> arr{1, 2, 3, 4, 5, 6, 7, 8, 9, 0};for(const auto i : arr){std::cout << i << ' ';}
}
6.2 用于编译时返回值确定的函数
#include <iostream>constexpr double sum(double d)
{return d > 0 ? d + sum(d - 1) : 0;
}
int main(void)
{constexpr double d = sum(5);std::cout << d;
}
6.3 用于自定义类对象
#include <iostream>struct X
{int value;
};int main()
{constexpr X x = { 1 };char buffer[x.value] = { 0 };
}
有想法对这个特性详细了解的童鞋可以参考:https://blog.csdn.net/SuperYang_/article/details/140575320