C++1x tutorial 学习笔记(1-3,8,9章)

C++1x学习笔记

弃用特性(不建议再使用)

  1. 弃用关键字/操作
  • register
  • export特性
  • bool类型变量的自增操作(++)
  1. 替换关键字/操作
  • auto_ptr -> unique_ptr
  • 字面值常量赋值给char *变量被弃用 -> 赋值给const char *或auto
  • C语言风格类型转换 -> static_cast/reinterpret_cast/const_cast
  • unexpected_handler/set_unexpected() -> noexcept
  • 参数绑定 -> std::bind/std::function
  1. 类操作
  • 类有析构,则为其生成拷贝构造和拷贝赋值的特性被弃用
  1. 兼容方式
  • C++不是C的超集
  • 使用extern "C"处理C语言风格代码
  • 分离编译再统一链接

C++11新特性

语言优化
  1. NULL -> nullptr
  • NULL不再等同于0
  • nullptr类型为nullptr_t
  • nullptr支持隐式转换为任何指针
  • nullptr支持与任何指针进行相等或不等的比较
  1. 使用关键字constexpr声明函数编译为常量
  • 可以使用constexpr函数结果定义数组大小
  • 支持函数递归
constexpr int fibonacci(const int n) // ok in cpp11 and upper
{
    retrun n == 1 || n == 2 ? 1 : fibonacci(n-1) + fibonacci(n-2);
}
constexpr int fibonacci2(const int n) // ok in cpp14 and upper
{
    if (n == 1) retrun 1;
    if (n == 2) return 1;
    return fibonacci(n-1) + fibonacci(n-2);
}
  1. 类型推导auto、decltype
  • 几个auto常见case
auto i = 6.0; // 普通变量声明
for(auto i = v.begin(); i != vec.end(); ++i) {} // 迭代器
auto arr = new auto(10); // 动态值声明,此例推导为int *
  • auto不能使用的情况
int add(auto x, auto y); // 编译失败,不能用于参数传参
int a[2] = {0}; auto b = a; // 错误,不能用于推导数组类型
  • decltype用于解决auto只能对变量进行推导的缺陷
auto x = 1;
auto y = 2;
decltype(x+y) z;
  • auto与decltype配合尾返回类型实现模板
template<typename T, typename U>
auto add(T x, U y) -> decltype(x+y)
{
    return x + y;
}
template<typename T14, typename U14>
auto add(T x, U y) // ok in cpp14 and upper
{
    return x + y;
}
  1. 范围for循环
  • cpp11可实现基于范围的迭代,类似于python语法
std::vector<int> arr(7, 10);
for (auto &i : arr) {++i;} // '&'符号决定变量能否修改
  1. 初始化列表
  • 允许绝大多数类型用{}的统一初始化方式进行初始化
struct A {int a; float b;};
struct B
{
    B(int _a, float _b): a(_a),b(_b) {}
private:
    int a;
    float b;
};
A a {5, 5.0};
B b {7, 7.0};
  1. 外部模板
  • 允许使用extern关键字显示告知编译器实例化时机
extern template class std::vector<SelfDefClass>; // 声明不在当前文件实例化
  1. 模板默认类型
  • 新增置顶模板默认类型的功能支持
template<typename T = int, typename U = double>
auto add(T x, U y) -> decltype(x + y) {return x + y;}
  1. 变长参数模板
  • 支持类似printf函数参数的情况
template<typename Require, typename... Args>
  • 使用sizeof...关键字可获取变长参数个数
template<typename... Args>
void Count<Args... arg>
{
    std::cout << sizeof...(args) << std::endl;
}
  • 递归模板函数和初始化列表展开是两种常见参数解包方法(详见26-27页)
  1. typedef -> using
  • using写法拥有比typedef更强的功能
using pfun = int(*)(void *); // 提高可读性
template<typename T, typename U>
class ExampleType;
using TempType = ExampleType<int, double>; // 支持实例化模板别名
  1. 构造函数增强
  • 支持委托构造
class A
{
public:
    int a, b;
    A() {a = 1;}
    A(int _b) : A() // 先调用委托函数,再执行函数体
    {
        b = _b;
    }
};
  • 支持继承构造
class B : public A
{
public:
    using A::A; // 继承基类A的所有构造函数
};
  1. 虚函数重载增强
  • override关键字用于显式告知编译器重载
struct A {virtual void func(int)};
struct B : A {virtual void func(int) override;} // 编译器会检查基类是否存在对应虚函数,不存在会编译失败
  • final关键字防止子类重载虚函数
struct C {virtual void func() final;} // 子类不可再重载该函数
  • final关键字另一个用法是防止类被继承
struct D final : C {}; // D类不可再被继承
  1. 类的默认函数强化
  • 使用default关键字显式声明使用默认函数
  • 使用delete关键字显示声明拒绝默认函数
class E
{
public:
    E() = default; // 使用默认函数
    E& operator=(const E&) = delete; // 拒绝默认函数
};
  1. 强类型枚举
  • 支持使用enum class声明枚举类
  • 枚举类类型安全,不能隐式转换为数字,必须显式类型转换
  • 枚举类类型可以指定枚举值类型(默认int)
  • 枚举类类型可以赋值
  • 枚举类类型可以为枚举值赋相同值
enum class SuperiorEnum : unsigned int
{
    a, // = 0
    b, // = 1
    c = 100,
    d = 100
};

运行期强化

  1. lambda表达式
  • 提供匿名函数的功能
  • 基本语法:

[捕获列表](参数列表) mutable(可选项) 异常属性 -> 返回类型 {函数体}

  • 捕获列表的几种形式

[] //空捕获列表
[v1, v2, ...] //捕获变量值,相当于函数传值
[&v1, &v2, ...] //捕获变量引用,相当于函数传引用
[&] //引用捕获,编译器自动推导变量列表
[=] //值捕获,编译器自动推导变量列表

  • 表达式捕获(cpp14以上支持)
auto pa = std::make_unique<int>(1);
auto add = [v1 = 1, v2 = std::move(pa)](int x, int y) -> int
{
    return x + y + v1 + (*v2);
}
  • 泛型lambda(cpp14以上支持)
auto add = [](auto x, auto y) {return x + y;}; // 定义泛型lambda
add(1.1, 2.2); // 使用泛型函数
  1. 函数的容器std::function
  • 相对函数指针类型安全
int func(int a) {return a * a;}
std::function<int(int)> f = func; // 定义了func函数的一个封装
std::cout << f(2) << std::endl; // 输出4
  1. 函数调用参数绑定std::bind
  • 常配合占位符std::placeholder进行使用
int f(int a, int b, int c) { return a / b + c; }
auto subf = std::bind(f, std::placeholders::_1, 2, 1); //subf被绑定了第2、3参数分别为2、1的函数
std::cout << subf(5) << std::endl; //输出3
  1. 右值引用
  • 左值:表达式处理后依然存在的持久对象
  • 右值:纯右值 + 将亡值
  • 纯右值:字面量、匿名临时变量、非引用返回的临时变量、运算表达式产生的临时变量、原始字面量、Lambda表达式

10 true 1+2

  • 将亡值:即将被销毁,能被移动的值
  • 使用T &&(T是类型)可通过右值引用拿到将亡值,临时延长其生命周期
  • 使用std::move将左值无条件转换为右值
std::string str = "string";
//std::string&& rf1 = str; // 错误,右值引用不能引用左值
std::string rf2 = std::move(str); // ok
  • 右值引用解决了旧C++不区分移动和拷贝的问题。
  • 使用std::forward实现完美转发

杂项

  1. long long int
  • 正式纳入标准库,至少64比特
  1. noexcept
  • 函数名后使用
void no_err_throw() noexcept; // 不允许抛出异常
  • 修饰函数使异常不扩散,若被noexcept修饰的函数抛出异常则系统会调用std::terminate()终止程序
  • 可以做操作符使用
noexcept(*express*); // 无异常返回true,反之返回false
  1. 字符串字面量
  • 新增R括号语法避免转义符的使用,类似python中的r用法
std::string str = R"(C:\What\The\Fxxk)"; //大写R,字符串用括号包裹
  • 新增整型、浮点型、字符串、字符字面量拼接,通过重载双引号操作符实现
std::string   operator"" _rank (unsigned long long i)
{
    return std::to_string(i)+"th";
}
// useage:
auto num_rank = 5_rank; // num_rank = "5th"
  1. 尖括号 >
  • 处理了嵌套模板>>导致被当做右移符编译出错的问题
std::vector<std::vector<int>> a; // ok in cpp11 and upper

C++17特性

  1. 非类型模板参数auto
  • 允许在模板中使用auto进行类型推断
  1. std::variant()
  • 集合,内部可容纳各种类型
  1. 结构化绑定
  • 允许类似python的多返回语法
std::tuple<int, double, std::string> f() // 函数定义
{
    return std::make_tuple(1, 2.3, "456");
}
// useage:
auto [x,y,z] = f(); // x,y,z自动推断为相应类型
  1. 变量声明强化
  • 允许在if和switch语句中声明临时变量,类似之前for循环声明临时迭代器的语法
if (auto p = map_container.try_emplace(key,value); !p.second) {;} // allow in c++17

未加入特性

  1. concepts
  • 类似python语言中的sortable、countable概念声明,用来优化模板编程不能在编译期间检查的体验
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,445评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,889评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,047评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,760评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,745评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,638评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,011评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,669评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,923评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,655评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,740评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,406评论 4 320
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,995评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,961评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,023评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,483评论 2 342

推荐阅读更多精彩内容