重载
加号重载
对于内置的数据类型,编译器知道怎么搞
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| #include <iostream> #include <string> using namespace std; class Person { public: int m_b; int m_a; Person operator+ (int n){ Person teep; teep.m_a = this->m_a+n; teep.m_b = this->m_b+n; return teep; } }; Person operator+ (Person &p1,Person &p2){ Person teep; teep.m_a = p1.m_a+p2.m_a; teep.m_b =p1.m_b + p2.m_b; return teep; }
|
重载左移运算符
1 2 3 4 5 6
| ostream &operator<<(ostream &out, Person &p) { out << "m_a=" << p.m_a << " m_b=" << p.m_b << endl; return out; }
|
递増运算符重载
一个前置运算符
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| Person &operator++() { this->m_b++; this->m_a++; return *this; } Person operator++(int) { Person tmep = *this; this->m_b++; this->m_a++; return tmep; }
|
仿函数
1 2 3 4 5 6 7 8 9 10 11 12
| class Person { void operator() (int a){ cout << a; } } void test01(){ Person b; b(1); Person()(2); }
|
继承
语法
为了减小重复的代码
语法: class 子类 :继承方式 父类
1 2 3 4 5 6 7 8 9 10
| class A{ public: int m_a; int m_b; }; class B:public A { int m_c; };
|
继承方式
继承方式
- 公共
- 保护
- 私有
如下规则:
- 父类中的保护权限儿子都拿不到
- 共有的父类的成员权限不变
- 保护-> 父有成员权限变为保护(私有同理)
继承中的对象模型
1 2 3 4 5 6 7 8 9 10 11 12 13
| class A{ public: int m_a; int m_b; protected: int m_d; private: int m_f; }; class B:public A{ int m_c; };
|
继承中构造和析构的顺序
构造 先父再子
析构 先子后父
同名成员
父类同名加作用域
注意:
- 如果是同名函数,编译器会隐藏同名函数(包括重载)
- 同名成员
多继承语法
class 子类: 继承方式 父类1,继承方式 父类2,继承方式 父类3
{
}
同名加作用域!!!
菱形继承
多态
用法
分为两类:
- 静态多态: 函数重载 和运算符重载
- 动态多态: 派生类和虚函数实现运行是多态
区别:
- 静态多态的函数地址早绑定 (编译阶段)
- 动态多态的函数地址晚邦定 (运行阶段)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| #include <iostream> #include <string> using namespace std;
class dong{ public: virtual void speak(){ cout << "dong" << endl; } };
class Cat :public dong { public: void speak(){ cout << "cat" << endl; } };
void dospeak(dong & animal){ animal.speak(); } void task01(){ Cat cat; dospeak(cat); } int main(){ task01(); }
|
多态原理
- 虚函数存储一个指针
vfpter
指向一个vftable
(表内记录虚函数入口地址)
- 如果子类重写了虚函数表 那指针指向入口就被重写的函数覆盖了(指向子类入口了)
- 当父类指针或者引用指向子类对象时候,发生多态
1 2
| father & fathe = son; father.speak();
|
纯虚函数& 抽象类
抽象类:
- 只要有一个纯虚函数就叫抽象类
- 无法实例化对象
- 抽象类的子类 必须要重写父类中的纯虚函数,不然也是抽象类
虚析构和纯虚析构
如果子类中有属性开辟到堆区 ,那么父类指针在释放时无法调用到子类的析构代码