- 类的声明
class A {
public:
A() = default; //使用默认的构造函数
A() = delete; //禁用此构造函数
//析构函数不能delete 如果为private/删除,则【默认/拷贝构造函数为private删除】
//类有析构函数,也需要拷贝构造和拷贝赋值函数
virtual ~A(); //有继承的情况下,一般声明为虚析构函数,这样子才能多态释放内存
//拷贝构造函数 不传引用会导致陷入死循环 涉及堆上申请内存,需要进行深拷贝,即手动分配内存
//类有拷贝操作 <==> 也需要赋值操作
A(const &A a) {}
};
A a; //调用类的构造函数
//以下都是:调用类的拷贝构造函数
A b(a);
A c = a; //由于此时c还没有初始化完成,编译器进行优化只调用类拷贝构造
A d; //调用类的构造函数
d = a; //先调用类的拷贝构造函数 和 operators= 重载运算符
A e = (int)1; //若有一个构造函数的形参为1个int就匹配,进行调用
A f;
f = 1; //调用拷贝构造函数,其形参生成一个临时的对象,这个对象调用int形参的构造函数
const
- const的初始化:只能在初始化列表进行初始化
- cons可以修饰成员函数,写在最后面,例如
void myFunc() const;
表示此函数的this指针为常量指针,无法修改成员属性等
RVO 返回值优化
RVO(Return value optimization) C++的一项编译优化技术
- 省略函数返回对复制构造函数的多余调用,解决临时对象效率问题
多继承棱形问题
-
当有一个父类A,分别有2个子类B、C分别继承A类,然后又有一个类D同时多继承B类和C类,这就构成了棱形问题。这会导致例如调用一样名字的方法时,编译器不知道要调用哪一个类的方法
-
解决方法:1)可以使用例如在C类里, B::run() 或 C::run() 来进行指定哪一个
2)使用虚继承,即B、C类继承A类时,A类前加上virtual关键字进行虚继承,这样会让B、C类有一个指向A类的指针vptr
C++11的一些关键字
auto
- 在C98的作用:具有自动存储期的变量
- 作用在编译期,可以自动推导类型
1)C++14开始才能作为函数参数
2)不能作为模版参数
3)无法定义数组
4)不能用于非静态成员变量
typeid
- C++运算符:获取类型信息,例如
typeid(int).name();
constexpr
- 编译期常量: 修饰函数、普通函数、构造函数,变量等
final
- 禁止类进行继承
- 禁止虚函数重写
override
- 表示对父类的函数进行重写,若父类没有此同名函数则会报错
nullptr
- 表示空指针
右值引用&&
- T& 左值引用只绑定左值,即能处于赋值等号左边的
T&& 右值引用只绑定右值,若为已命名的则编译器会认为是左值,即能处于赋值等号右边的
const T& 常量左值引用可以绑定左值和右值
引用转换 forward move 与 移动构造
- forward 完美转换,即原来是什么类型就传递什么类型,例如
forward<int&&>(a);
- move 转换为右值
- move constructor移动构造:可以将右值拿过来使用(内存分配+初始化),效率比拷贝构造函数高
decltype
- 自动推导出变量的类型
decltype(1 + 2) a; //等价于 int a;
std::conditional
std::conditional <表达式, 类型1, 类型2>
:如果表达式为真则定义的变量为类型1,如果表达式为假则定义的变量为类型2
std::function
- 一个函数对象,用于表示函数这个抽象概念
- 此实例可以对任何可以调用的目标实体(例如普通函数,仿函数,lambda匿名函数,模版仿函数,类的静态成员函数,类的成员函数等),进行存储、复制、和调用操作
#include <functional>
using namespace std;
//语法
function<函数返回值(params...)>
void func(int a) { ... }
function<void(int)> f = func;
仿函数
- 实现了**operator()**运算符的类
std::bind
- 将函数转换成新函数对象,返回一个新的函数对象
- **std::ref()**在模板传参的时候传入引用,否则无法传递
#语法
bind(func_name, arg1, arg2...);
bind(func_name, std::placeholders::_1, std::placeholders::_2 ...);
特殊绑定 bind1st(), bind2nd()
- 将二元函数对象(modulus, less等等) 转换为一元函数对象
智能指针
unique_ptr
shared_ptr
weak_ptr
std::thread
- 用在多线程并发
std::mutex
std::atomic
- 模版类,原子操作
函数/类模版
模版多态
- 编译阶段,属于多态里面的静态多态
- 关键字ytpename和class可以互换,定义如下
//函数模版定义
template<typename type> 返回值 函数名(形参) { ... }
//类模版定义
template<class type> class 类名 { ... }
//不定参数模版
template<class T> T sum(T t) { return t; }
template<class T, class ...ARGS> T 函数名(T t, ARGS ...args) { return t + sum(args...); }
泛型/函数式编程
- 即C++的模版元编程,满足图灵完备性
图灵完备性
-
只要满足以下特效,就可写出任何需求程序
-
有基本的数据类型:字符串,数字等
-
将基础类型组合起来的某种方法,表达更高级概念:C语言的struct,数组,字典
-
流程控制:顺序、分支、循环
-
输入和输出