C++11新特性
C++11新特性
语言特性
-
移动语义
-
右值引用
-
转发引用
-
可变模板
-
列表初始化
列表初始化,就是使用花括号进行初始化
std::vector<int> nums{1, 2, 3, 4, 5}; // 列表初始化 for (auto it : nums){ cout << it << endl; }
-
静态断言
编译时断言机制,允许在编译时检查某个条件是否为真。静态编译检查编译时的常量表达式。经常与类型特征
type traits
一起使用。因为静态断言是在编译时进行检验,所以可以用于不同编译平台进行运行前检验。static_assert(<constant-expressions>, <error-message>); static_assert(sizeof(int) >= 4, "Not support 32 bits integer"); template <typename T> void CheckInt(T* co, size_t size) { static_assert(std::is_integral<T>::value, "Not support 32 bits integer."); }
-
类型推导
auto
类型推导的使用,必须前面有可以隐式说明类型的语句。std::vector<int> nums; for (auto it : nums){ cout << it << endl; }
-
lambda表达式
-
decltype
类型声明decltype操作符将会返回传递给它的表达式得到的类型。
int a = 0; decltype(a++) b;
-
类型别名
C++
中using
也可以声明别名,相较于typedef
更易读。template <typename T, typename T> using u_map = std::map<T, T>;
-
nullptr
空指针nullptr
空指针的使用可以规避掉以往设置为NULL
的风险。NULL
在编译器中常常被设置为0
或者其它数字,此时判断指针是否为NULL
,即判断指针类型是否能够等于整型值,并不安全。int* p = nullptr;
-
强类型枚举
强类型枚举不能隐式转换为
int
类型,可以指定底层类型,如果未指定底层类型,会自动默认为int
类型。只能通过类型名访问,是因为成员作用域局限在类型中,并不公开。// 强类型枚举 enum class HttpState:uint32_t{ HTTP_OK, // private HTTP_BAD }; using State = HttpState; State state = State::HTTP_OK;
-
constexpr
声明constexpr
会告诉编译器在编译时对其进行优化,所以会在编译时即计算完。因此禁止调用运行时才完成的函数(如构造函数)。constexpr int Add(int a, int b) { return a + b; } int main(){ int a =3, b = 4; const int res = Add(a, b); std::cout << res << std::endl; }
-
委托构造
构造器能够调用其它构造器进行初始化。
class MyClass{ MyClass(int a) :val(a){}; // default private MyClass() : MyClass(0){}; private: int val; }
-
用户定义语义
-
显式虚重载
override
告知编译器,派生类会覆盖基类中的虚函数,避免发生签名不匹配和不存在相应虚函数。如果出错会报错。// explict virtual override class Base{ virtual void Add()=0; }; class Derived final: public Base{ void Add() override{ /* code */ }; };
-
Final
限定符告诉编译器,用于指示一个类不能被进一步继承,或者一个虚函数不能被子类覆盖。
// final修饰的虚函数无法覆盖 class Cat{ public: virtual void showCatName() final{ // 限定不能被继承 /* 显示名字 */ } }; class MyCat : public Cat{ void showCatName(){ // 不能继承父类,此时会编译报错 /* ... */ } } // final修饰的类无法继承 class Base final{ virtual void Add() = 0; };
-
default
修饰符此修饰符用于告诉编译器为
default
修饰的函数生成默认函数,noexcept
告诉编译器不要抛出异常,避免对象构建过程中抛出异常,假如构造函数抛出异常,其中有一些变量已经生成。那么此时对象无法构建成功,已经生成的变量则无法析构,会导致丢失内存。class Myclass{ Myclass() noexcept = default; // 生成默认配置 };
-
deleted
修饰符此修饰符用于告诉编译器不要为
delete
生成默认的函数,使其无法被实例化和调用。可以完成禁止拷贝、禁止移动等功能。class Myclass{ Myclass() noexcept = delete; // 禁止生成默认配置 };
-
范围
for
循环std::vector<int> nums; for (auto it : nums){ cout << it << endl; }
-
移动语义特殊成员函数
-
显式转换功能
-
内联命名空间
-
非静态数据成员初始化
-
右角括号
-
引用限定成员函数
-
尾部返回类型
允许lambda和函数指定返回类型。
-
noexcept
限定符:限定能否抛出异常noexcept
关键字告诉编译器该函数不会抛出任何异常,从而允许编译器优化。如果抛出了异常,会用std::terminate
终止程序运行。可以省略一些编译器生成一些异常处理代码。可以是条件性判断抛出异常。void Add(int a, int b) noexcept{ // 不会抛出任何异常 } void AddIf(int a, int b) noexcept(false){ // 可能会抛出异常 }
-
char32_t
char16_t
代表UTF-8
字符串(1-4个字节) -
原始字面字符串
库特性
-
std::move
-
std::forward
-
std::thread
thread
是引入的线程库。 -
std::to_string()
to_string
能够完成的作用是将数字转换为字符串。stoi()
函数将字符转为数字,一定要注意提前检查字符一定是数字,而不是数字意外的其它字符,否则会程序崩溃。 -
type_traits
类型特性库类型特性库包含了一组编译时检查类型特性的工具,可以配合
static_assert
使用。// 基本类型判断包括整型、浮点型等 std::is_integral<T>::value // 检查T是否是整数类型,value是一个静态常量,其值为true或false // 类型修饰 std::remove_const<T> // 移除类型T的const修饰 // 类型转换 std::add_const<T> // 为类型T添加const修饰 // 类型特性检查 std::is_same<T, U> // 检查两个类型是否相同 // 条件类型 std::conditional<Condition, T, F> // Condition为true, 则类型为T,否则为F
-
智能指针
智能指针有三种,
share_ptr
共享指针,用于多个读;weak_ptr
弱指针,解决共享指针循环引用计数无法下降问题;unique_ptr
独占指针,用于独享资源。 -
std::chrono
chrono
是引入的一个定时器相关的库,有system_clock
-
turples
-
std::tie
绑定 -
std::array
数组容器,有强制类型检查,连续存储可以告诉访问,可以用于存储特定个数元素。
vector
是可以扩容的。std::array<int> intArray{1, 2, 3, 4, 5};
-
unordered containers
-
std::make_shared
-
std::ref
-
std::async
-
std::begin()
和std::end()
这两个函数用于获取对象的迭代器,
begin(string str)
等价于str.begin()
。