C++11新特性笔记

C++11新特性

《C++ Primer Plus》笔记

统一的初始化

使用大括号进行初始化
使用大括号形式不能进行缩窄形式的类型转化

int x = {5};
double y{3.14};
short a[]{5, 4, 3, 2, 1};
int *ar = new int[4] {10, 9, 8, 7};
char c = {459585821}; // 非法初始化

声明变量

auto

auto a = 10; // 自动推断为int类型
auto b = vec.begin(); // 自动推断为vector::iterator类型

decltype

将变量类型声明为表达式指定类型

double x = 2.3;
int y = 1;
decltype(x * y) q; // 将q声明为x*y的结果相同的类型

智能指针

auto_ptr已被C++11摒弃
unique_ptr只能是一个指针指向一个对象
shared_ptr多个指针指向一个对象

异常相关

提出了新关键字noexcept,表示不会抛出异常

void fun() noexcept {

}

作用域内枚举

使用class或struct关键字定义枚举,使用时加上作用域名称

enum class Color{red, yellow, green, blue}; 

auto x = Color::red;

显示转换运算符

explicit关键字防止类构造函数使用自动转换,C++11扩展到可以对转换函数使用

class Plebe {
    ...
    operator int();
    explicit operator double();
}

Plebe a, b;
int n = a; 
double x = b; // 非法转换
double x = double(b);

STL修改

新增新的for循环方法和若干STL容器类

右值引用

在引用中,无法对右值添加引用

int num = 10;
int &a = num; // 支持
int &b = 10; // 报错

右值引用使用&&

int num = 10;
int &&a = num; // 右值引用不能初始胡为左值
int &&b = 10; // 支持

移动语义

移动语义避免移动原始数据,而只是修改记录,使用右值引用实现

移动构造函数

将原对象中的数据移动到新的对象中,而不是进行深拷贝

当类中同时存在拷贝构造函数和移动构造函数时,如果使用临时对象初始化当前的类对象,则有限调用移动构造,若没有移动构造函数,则调用拷贝构造函数。

class Test {
private:
    int n;
    char* str;

public:
    Test(int n, char* str);
    // 普通的复制构造函数
    Test(Test t);
    // 移动构造函数
    Test(Test&& t);

    Test operator +(const Test& t) const;
}

Test::Test(Test t) {
    n = t.n;
    str = new char[n];
    for(int i = 0; i < n; i++) {
        str[i] = t.str[i];
    }
}

Test::Test(Test&& t) {
    n = t.n;
    str = t.str;
    t.str = nullptr;
    f.n = 0;
}


Test a(3,"abc");
Test b = a; // 调用拷贝构造函数
Test c = a + b; //调用移动构造函数

移动赋值运算符

类似于移动构造函数

虚方法管理

override

override指出需要覆盖的虚函数,放在参数列表后面,如果声明与基类方法不匹配,则报错

final

final指出该方法不能被被派生类覆盖

Lambda表达式

Lambda语法

// []表示Lambda函数外的变量,()表示形参,{}表示函数体
[&count](int x){count += (x % 13 == 0);}
auto f = [](int x) {return x == 13;};
bool res = f(a);

包装器(适配器)

下面的代码中,模板函数会生成3个实例化方法,导致效率低下

template<class T, class F>
T void use_f(T v, F f) {
    return f(v);
}

void fun1(double x) {
    return x + 1;
}

void fun2(double x) {
    return x * 2;
}

class Class1 {
publc:
    double operator()(double x) {
        return x + 1;
    }
}

class Class2 {
publc:
    double operator()(double x) {
        return x * 2;
    }
}

double x = 1.0;
double x1 = use_f(x, fun1); // use_f(double, double(*)(double))
double x2 = use_f(x, fun2); // use_f(double, double(*)(double))
double x3 = use_f(x, Class1()); // use_f(double, Class1)
double x4 = use_f(x, Class2()); // use_f(double, Class2)

使用包装器function只会生成一种实例化方法

template<class T>
bool fun(T v, std::Function<bool(int)> f) {
    return f(v);
}

std::function<double(double)> f = [](double x) {return x * 2;};
double x = 1.0;
// use_f(double, std::function<double(double)>)
double x1 = use_f(x, fun1); 
double x2 = use_f(x, fun2); 
double x3 = use_f(x, Class1()); 
double x4 = use_f(x, Class2()); 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值