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 类型的参数,表示摄氏度的值。该运算符将摄氏度转换为华氏度,并返回转换后的值

posted @ 2023-06-26 20:52  言叶以上  阅读(22)  评论(0编辑  收藏  举报