C++11特性简单介绍
自动类型推导auto
auto x = 10; // 推导x为int类型
auto str = "Hello"; // 推导str为const char*类型
基于范围的For循环
for(int& i: someDataStructure) { doSomething();}
for(int i: someDataStructure) doSomething();
在上面的两个for循环中,第一个使用引用,第二个启用按值访问。第一种方法允许修改数据结构中的元素,第二种方法不能修改正在使用的容器中的元素。
强类型枚举
使用class关键字限定了作用域, 例如,坐标系中有四个领域: 第一、第二、第三和第四。它以坐标线为界:
enum class CoordinateArea { FirstArea, SecondArea, ThirdArea, FourthArea};
CoordinateArea caOne = CoordinateArea::FirstArea;
CoordinateArea caSome= CoordinateArea::FourhtArea;
Lambda函数的Lambda表达式
一种定义匿名函数的方式,能够在需要函数对象的地方使用, 就像一个函数有一个函数体,但没有名字。它们的声明如下:
[firstPart](secondPart) TypeYouReturn{ BodyOfLambda}(acctualParameters);
- firstPart用于将在lambda函数中使用的变量范围, [], [&], [=], [this]
- secondPart对于无名函数的参数列表是必需的,但它也可以留空
- TypeYouReturn用于注册将从lambda返回的类型
- BodyOfLambda用于您希望执行的操作
- actualParameters用于向lambda函数提供输入
double dUpperPart = [](double dX, double dY)double{ return dX*dX +dY*dY;}
vectror<int> iVector;
for_each( begin(iVector), end(iVector), [](int n){if(n%2==0)cout<<n<<end;});
静态断言
C++11引入了static_assert关键字,用于在编译时对表达式进行断言检查
用法: static_assert(evaluatedExpression, stringMessage);
static_assert(sizeof(long long int)>=16;”This is unexpected”);
Move 和 &&
在旧的标准中,我们只能使用左值作为引用,现在已经改变了,你也可以使用右值作为引用。它在需要复制一些对象的情况下很有用,更好的解决方案是使用移动语义。
std::string str1 = "Hello";
std::string str2 = std::move(str1); // 移动str1的资源到str2
类中应用move构造函数:
MovableClass(MovableClass&&);
移动赋值:
MovableClass&& operator=(MovableClass&&);
关于指针
- 用nullptr替换NULL
- 智能指针: unique, shared 和 weak.
- unique_ptr,它可以保护存储在内存中的某些资源的所有权。如果某个东西有所有权,它就不能被共享,但它是可移动的。这意味着您可以将其转移到另一个唯一指针。
- shared_ptr 适用于需要共享内存中某些资源的所有权的情况。
- weak_ptr允许访问内存中可能存在的内容,如果有占用内存的对象,则授予访问权限,并且可以删除该对象,如果上次使用过,则调用必要的析构函数。
unique_ptr<someType> suniquePtr(new someType(args));
...
uniquePtr.release();
shared_ptr<someType> somePtr(new someType(args));
weak_ptr<someType> weakPtr= somePtr;
统一初始化和初始化程序列表
构造函数:
CSomeClass SomeObject( argument1, argument2);
CSomeClass SomeObject={ argument1, argument2};
如果你想把一些值放入vector中,通常使用push_back几次,或者使用旧风格的括号进行初始化,这是可以实现的,现在已经过时了:
vector <int> ourVector;
for(int i=0; i<5; ourVector.push_back(i++));
vector< int> ourVector={0,1,2,3,4,};
类型别名
using MyInt = int;
using PersonMap = std::map<std::string, Person>;
委托构造函数
C++11允许一个构造函数调用同一类的其他构造函数,从而避免了冗余的初始化代码。这使得构造函数之间的代码共享更加方便
class Point {
public:
Point() : Point(0, 0) {}
Point(int x, int y) : m_x(x), m_y(y) {}
private:
int m_x;
int m_y;
};
constexpr 函数和常量表达式
C++11引入了constexpr关键字,用于指定函数或变量的值可以在编译时计算。这使得编译器能够在编译时进行优化,提高程序性能
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}
constexpr int result = factorial(5); // 在编译时计算阶乘结果
原始字符串字面量
使用原始字符串字面量来表示字符串,这样可以更轻松地编写包含转义字符的字符串
std::string path = R"(C:\Program Files\MyApp\)";
非静态成员的初始值
class Person {
public:
std::string name = "John";
int age = 30;
};
默认和删除的函数
class MyClass {
public:
MyClass() = default; // 显式声明默认构造函数
MyClass(const MyClass&) = delete; // 禁用拷贝构造函数
};
多线程库
C++11引入了
std::thread 类用于表示一个线程对象
void myFunction() {
// 线程执行的代码
}
std::thread t(myFunction); // 创建新线程并执行 myFunction 函数
- join() 方法会阻塞当前线程,直到被调用的线程执行完成
- detach() 方法将线程与创建它的对象分离,使得线程可以独立执行,不再与创建它的对象关联
- std::mutex 和 std::lock_guard:用于提供互斥访问
- std::condition_variable:用于线程间的条件变量同步,可以实现线程的等待和唤醒机制
- std::atomic:用于原子操作,确保在多线程环境下对共享变量的操作是原子的
字面量运算符
自定义字面量由两部分组成:字面量运算符(Literal Operator)和字面量后缀(Literal Suffix)
字面量运算符是一个函数,用于解析并处理字面量的值。它以前缀 operator"" 开头,后面跟着字面量后缀标识符和参数,可以是整数、浮点数、字符或字符串等。
#include <iostream>
// 定义自定义字面量运算符,用于将摄氏度转换为华氏度
constexpr double operator"" _C(long double celsius) {
return celsius * 9 / 5 + 32;
}
int main() {
// 使用自定义字面量运算符来表示摄氏度,并将其转换为华氏度
double temperature = 25.0_C;
std::cout << "摄氏度: 25.0\n";
std::cout << "华氏度: " << temperature << std::endl;
return 0;
}
上述示例定义了一个自定义字面量运算符 operator"" _C,它接受一个 long double 类型的参数,表示摄氏度的值。该运算符将摄氏度转换为华氏度,并返回转换后的值