C++其他语法总结
一、运算符重载
- 运算符重载可以为运算符增加一些新的功能
 - 全局函数、成员函数都支持运算符重载
 - 常用的运算符重载示例
 
class Point {
	// friend Point operator+(const Point &, const Point &);
	friend ostream &operator<<(ostream &, const Point &);
	friend istream &operator>>(istream &cin, Point &point);
	int m_x;
	int m_y;
public:
	Point(int x, int y) :m_x(x), m_y(y) {}
	void display() {
		cout << "(" << m_x << ", " << m_y << ")" << endl;
	}
	Point(const Point &point) {
		m_x = point.m_x;
		m_y = point.m_y;
	}
	const Point operator+(const Point &point) const {
		return Point(m_x + point.m_x, m_y + point.m_y);
	}
	const Point operator-(const Point &point) const {
		return Point(m_x - point.m_x, m_y - point.m_y);
	}
	Point &operator+=(const Point &point) {
		m_x += point.m_x;
		m_y += point.m_y;
		return *this;
	}
	bool operator==(const Point &point) const {
		return (m_x == point.m_x) && (m_y == point.m_y);
	}
	bool operator!=(const Point &point) const {
		return (m_x != point.m_x) || (m_y != point.m_y);
	}
	const Point operator-() const {
		return Point(-m_x, -m_y);
	}
	// 前置++
	Point &operator++() {
		m_x++;
		m_y++;
		return *this;
	}
	// 后置++
	const Point operator++(int) {
		Point old(m_x, m_y);
		m_x++;
		m_y++;
		return old;
	}
};
// output stream -> ostream
ostream &operator<<(ostream &cout, const Point &point) {
	cout << "(" << point.m_x << ", " << point.m_y << ")";
	return cout;
}
// input stream -> istream
istream &operator>>(istream &cin, Point &point) {
	cin >> point.m_x;
	cin >> point.m_y;
	return cin;
}
 
- 子类调用父类的运算符重载函数:需要指定类名

 - 单例模式中,可以将=号重载成为私有的,这样可以避免被重新赋值

 - 运算符重载的注意事项 
  
- 有些运算符不可以被重载,比如 
    
- 对象成员访问符号:.
 - 域运算符:::
 - 三目运算符: ? :
 - sizeof
 
 - 有些运算符只能重载为成员函数,比如: 
    
- 赋值运算符:=
 - 下表运算符:[]
 - 函数运算符:()
 - 指针访问成员:->
 
 
 - 有些运算符不可以被重载,比如 
    
 
二、仿函数
- 仿函数:将一个对象当作一个函数一样来使用
 - 对比普通函数,它作为对象可以保存状态

 
三、模板(template)
- 泛型,是一种将类型参数化以达到代码复用的技术,C++中使用模板来实现泛型
 - 模板的使用格式如下: 
  
- template <typename\class T>
 - typename和class是等价的
 
 - 模板没有被使用时,是不会被实例化出来的,在编译时如果有几次不同类型的调用,编译器就会实现多少类的模板
 - 模板的声明和实现如果分离到.h和.cpp文件中,会导致链接错误,一般将模板的声明和实现统一放到一个.hpp文件中
 - 函数模板的实现如下:

 - 多参数模板如下:

 - 类模板示例如下:

 - 类模板中的友元函数如下:

 
四、类型转换
-  
c语言风格的类型转换
- (type)expression
 - type(expression)
 
 -  
c++中有4个类型转换符(适用格式:xxx_cast(expression)
- static_cast
 - dynamic_cast
 - reinterpret_case
 - const_case
 
 -  
const_cast:一般用于去除const属性,将const转换成非const

 -  
dynamic_cast:一般用于多态类型的转换,有运行时安全检测,会将不安全的转换设置为null

 -  
static_cast:
- 对比dynamic_cast,缺乏运行时安全监测
 - 不能交叉转换(不是同一继承体系的,无法转换)
 - 常用于基本数据类型的转换、非const转成const
 - 适用范围较广

 
 -  
reinterpret_cast
- 属于比较底层的强制转换,没有任何类型检查和格式转换,仅仅是简单的二进制数据拷贝
 - 可以交叉转换
 - 可以将指针和整数互相转换

 
 
五、c++ 11新特性
-  
auto
- 可以从初始化表达式中推断出变量的类型,大大简化编程工作
 - 属于编译器特性,不影响最终的机器码质量,不影响运行效率

 
 -  
decltype :可以获取变量的类型

 -  
nullptr:可以解决NULL的二义性问题

 -  
快速便利

 -  
更简洁的初始化

 
六、Lambda表达式
- 有点类似于javascript中的闭包,IOS中的Block,本质就是函数
 - 完整结构:[capture list] (params list) mutable exception ->return type { function body } 
  
- capture list:捕获外部变量列表
 - params list:形参列表,不能使用默认参数,不能省略参数名
 - mutable:用来说明是否可以修改捕获的变量
 - exception:异常设定
 - return type:返回值类型
 - function body:函数体
 
 - 有时可以省略部分结构:不能省略[],因为[]是lambda表达式的标志 
  
- [capture list] (params list) ->return type { function body }
 - [capture list] (params list) -> { function body }
 - [capture list] {function body}
 
 - lambda表达式示例 
  
- 定义一个lambda表达式变量,后期使用


 - 将lambda表达式直接执行

 - 将lambda表达式当作函数实参传递

 
 - 定义一个lambda表达式变量,后期使用
 - lambda表达式-外部变量捕获示例

 - lambda表达式-mutable

 
七、异常
-  
异常是一种在程序运行的过程中可能会发生的错误
 -  
异常没有被处理,会导致程序终止
 -  
c++中的异常可以被try…catch…,但是没有finally
 -  
throw异常后,会在当前函数中查找匹配的catch,找不到就终止当前函数代码,去上一层函数中查找。如果最终找不到匹配的catch,整个程序就会终止

 -  
异常的抛出声明:为了增强可读性和方便团队协作,如果函数内部可能会抛出异常,建议函数声明一下异常类型

 -  
自定义异常类型

 -  
拦截所有异常类型

 -  
标准异常(std中定义的标准异常)



 
八、智能指针
-  
智能指针就是在指针变量销毁时自动释放指向对象的内存(会调用类的析构函数)
 -  
传统指针存在的问题
- 需要手动管理内存
 - 容易发生内存泄漏(忘记释放、出现异常等)
 - 释放后产生野指针
 
 -  
智能指针就是为了解决传统指针存在的问题
- auto_ptr:属于c++98标准,在c++11中已经不推荐使用(有缺陷,比如不能用于数组等)
 - shared_ptr:属于C++11标准
 - unique_ptr:属于C++11标准
 
 -  
shared_ptr:共享指针
-  
shared_ptr的设计理念:多个shared_ptr可以指向同一个对象,当最后一个shared_prt在作用域范围内结束时,对象才会被释放
 -  
可以通过一个已存在的智能指针初始化一个新的智能指针

 -  
在数组中的用法如下:

 -  
shared_ptr的原理
- 一个shared_ptr会对对象产生强引用(strong reference)
 - 每个对象都有个与之对应的强应用计数器,记录着当前对象被多少个shared_ptr强引用着。
 - 可以通过shared_ptr的use_count函数获得强引用计数器
 - 当有一个新的shared_ptr指向对象时,对象的强引用计数就会+1
 - 当有一个shared_ptr销毁时,对象的强引用计数就会-1
 - 当一个对象的强引用计数为0时,对象就会自动销毁(析构)
 
 -  
shared_ptr的循环引用:智能指针指向的对象不会被销毁,导致内存泄漏

 
 -  
 -  
weak_ptr:弱指针
- weak_ptr会对一个对象产生弱引用
 - weak_ptr可以指向对象解决shared_ptr的循环引用问题


 
 -  
unique_ptr:唯一引用
- unique_ptr也会对一个对象产生强引用,它可以确保同一时间只有1个指针指向对象
 - 当unique_ptr销毁时,其指向的对象也会自动销毁
 - 可以使用std::move函数转移unique_ptr的所有权

 
 -  
自我模拟实现智能指针

 
后记
   个人总结,欢迎转载、评论、批评指正