您的位置:首页 > 编程语言 > C语言/C++

C++ 概念总结(基于 C++11)

2016-05-06 14:21 369 查看
C++ 概念总结(基于 C++11)

构造

构造函数形式:

默认构造函数

拷贝构造函数

定义: 当定义一个新对象并用一个同类型的对象对它进行初始化时,将显式使用复制构造函数

形式: A(const A& h){}

调用时机:

当对象作为参数传递时

赋值操作符:

定义: 赋值操作符可以通过制定不同类型的右操作数而重载。

形式: A& operator = (const A& h){}

调用时机:

当对象需要用 ‘=’ 进行赋值时

移动构造函数

定义: 源对象资源的控制权全部交给目标对象

形式: A(A && h){}

调用时机: 使用临时对象进行赋值

移动赋值操作符: 基本同上

C++11 中的是 构造函数被子类继承,并且是隐式的.

委派构造: 委派构造函数将构造任务委派给目标构造函数

委派构造函数不能带有初始化列表

C++ 中的 初始化形式更加多样

等号 “=”

等号加上花括号 int a = {3 + 4}

圆括号表达式 int a(3+4)

花括号初始化列表 int a{3+4}

对于自定义类需要借助 initializer_list 构造函数

移动语义

C++ 中的值类型分为 左值,右值,将亡值(可以简单的看成将被右值引用的值)

右值操作: std::move / std::forword

引用折叠: (&.. 总能被折叠为正确的 & / &&)

关于返回值

通常情况,从函数返回出来的对象是临时对象

当函数返回的那个对象本身是临时对象(作用域本身就在函数体内),那么返回的就是它

当函数返回的那个对象不是临时对象.那么会拷贝构造为临时对象

如果返回的对象是移动语义的,会移动构造一个临时对象 =.=!

如果返回引用值 T&

如果返回对象是临时对象,那么会出问题

如果不是临时对象,那么是这个东东的引用

如果返回的是移动语义的,编译器报错

如果 返回移动语义 T&&

只能接受 std::move 对象,直接返回临时对象

POD 类型

POD (Plain Old Data)字面上理解,是原始的数据,其体现了与 C 的兼容性,其优势如下

字节赋值,代码中我们可以安全地使用 memset/memcpy 对 POD 类型进行初始化和拷贝等操作

提供对 C 内存布局兼容. C++ 程序可以与 C 函数进行互相操作,因为 POD 类型的数据在 C 与 C++ 间的操作总是安全的

保证了静态初始化的安全有效.静态初始化在很多时候能搞提高程序的性能,而 POD 类型的对象初始化往往更加简单(比如放入目标文件的 .bss 段,在初始化中直接被赋 0).

满足 POD 类型的必须为 trival 或者 standard layout

trilvial

构造函数/析构函数/复制构造/移动构造/复制赋值运算符 必须为默认

不能包含虚拟函数和虚拟基类

standard layout

所有非静态数据成员均符合标准布局类型,其基类也符合标准布局.

所有非静态成员都有相同的访问权限

没有虚拟函数和虚基类

类中第一个非静态成员的类型与其基类不同 //因为 C++ 的标准中定义类型相同的对象必须地址不同!

在class或者struct继承时, 满足以下两种情况之一

派生类中有非静态成员, 且只有一个仅包含静态成员的基类.

基类有非静态成员,派生类没有非静态成员.

(换句话说,非静态成员不能同时存在于基类和派生类中咯?)

C++11 引入非受限联合体的支持

自定义字面量

内联名字空间

可以在父作用域直接被查找

ADL: 可以通过对象的名字空间直接推到出来

using 的扩展

可以取代 typedef

更加灵活的用法 template using MapString = std::map

动态类型

auto

可以通过 typeid 查询的类的相关信息

decltype 推到四规则(假设 e 是 T 类型)

如果没有带括号的标记符表达式或者类成员访问表达式,则返回推到类型 T = decltype(e) //表达式

否则,如果 e 是一个将亡值,那么返回 T&&

否则,如果 e 是一个左值,则返回 T&

否则,decltype(e) 的推到值为 T //对象 e

C++11引入枚举类: enum class Type{}

智能指针

智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放有它管理的堆内存

std::auto_ptr 管理从 new 形式获取的对象,在 auto_ptr 销毁的时候会释放这个对象.复制这个指针对象会导致它持有的对象移交所有权.

std::scoped_ptr 独享所有权,不可复制

std::shared_ptr 自带引用计数,看似完美

std::scoped_array 数组指针,也是禁用拷贝复制的

std::shared_array 数组指针,不再禁用拷贝复制

std::weak_ptr 引用,但不计数

std::intrusive_ptr 插入智能指针,需要手动增加计数

类型转换

隐式转换

算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。

一种类型表达式赋值给另一种类型的对象: 目标类型是被赋值对象的类型(void指针赋值给其他指定类型指针时,不存在标准转换,编译出错)

将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型

从一个函数返回一个表达式,表达式类型与返回类型不一致:目标转换类型为函数的返回类型

显式类型转换

static_cast < type-id > ( expression )

基本类型转换,但没有运行时类型检查来保证转换的安全性。

static_cast不能转换掉 const , volitale , __unaligned属性。

dynamic_cast < type-id > ( expression )

说明: Type-id必须是类的指针,类的引用或者void *;type-id / expression 必须同为指针或者引用。

dynamic_cast具有类型检查的功能

reinterpret_cast (expression)

关键字 re-interpret ->重解释! 不通类型之间的互转,任何转任何

const_cast (expression)

去常量性

lambda 表达式

[ capture ] ( params ) mutable exception attribute -> ret { body }

[] 不截取任何变量

[&} 截取外部作用域中所有变量,并作为引用在函数体中使用

[=] 截取外部作用域中所有变量,并拷贝一份在函数体中使用

[=, &foo] 截取外部作用域中所有变量,并拷贝一份在函数体中使用,但是对foo变量使用引用

[bar] 截取bar变量并且拷贝一份在函数体重使用,同时不截取其他变量

[x, &y] x按值传递,y按引用传递

[this] 截取当前类中的this指针。如果已经使用了&或者=就默认添加此选项。

常量表达式 constexpr

常量表达式函数:

函数体只有单一的 return

必须有返回值

使用前必须定义

返回语句表达式中不能使用非常量表达式的函数,全局数据,且必须是一个常量表达式

自定义类型常量,需要添加常量构造函数 constexpr T(){}

C++11 支持变长模板 //代表 => tuple

constexpr 为编译时确定

小技巧

Pragma 的新特性

预处理指令 #pragma xx

操作符形式 _Pragma(“xx”)

变长参数宏 : #define PR(…) printf(VA_ARGS)

静态断言: static_assert

noexcept: 禁止异常抛出

作为修饰符: void fun() noexcept

作为操作符: noexcept (常量表达式),常量表达式的结果会被转化为 bool 值, noexcept(noexcept(xx)) => 可以应用到模板

C++11全面支持就地初始化,但是参数列表的优先级更高

friend 的声明更加简单,并且支持模板 => friend T

final/override 添加了对成员方法的限制

模板函数的参数可以指定默认值了

外部模板,对于需要显式申明模板的情况(编译器优化),可以用外部声明替换

局部和匿名的类型可以作为模板的实参了.

原子操作模板: std::atomic

对齐支持: alignof / alignas

quick_exit/at_quick_exit
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++