一. 初始化列表 (初始化列表中必须有的两个内容)
1. 类中 const 的成员变量:
特点: 不能修改 必须初始化 在构造函数后面加冒号 格式为:": 变量名 (值)"
也就是说 常量必须在初始化列表中初始化
执行顺序: 构造函数先执行初始化列表 然后执行函数中的内容
- #include<iostream>
- using namespace std;
- class CPerson
- {
- public:
- const int a;
- public:
- CPerson():a(100)
- {
- }
- void Show()
- {
- cout <<a << endl;
- }
- };
- int main()
- {
- CPerson ps;
- ps.Show();
- return 0;
- }
2. 组合关系的类中的构造函数有参数:
例: 包含了另一个类的对象要执行指定的构造函数
- #include<iostream>
- using namespace std;
- class CHead
- {
- public:
- CHead(int a)
- {
- }
- };
- class CPerson
- {
- public:
- CHead head;
- public:
- CPerson():head(100)
- {
- }
- };
- int main()
- {
- CPerson ps;
- return 0;
- }
二. const 常函数和常量对象
1. 常函数:
基本格式: void Show() const{ .. }
特点: 不能修改类中的成员变量
可以理解为 常函数参数括号中传的指针已经变成 const CPerson* this 这种指针了 (拿 CPerson 为例)
也就是说 this 已经变成 const 类型 这种指针的指向是不可以修改的 但是可以使用
2. 常量对象:
格式: const CPerson ps;
特点: 常量对象只能调用常函数 不能使用普通函数
可以理解为 ps.Show(const CPerson*); 传入对象的地址类型不可改变
下面是一个常函数和常量函数的简单例子:
- #include<iostream>
- using namespace std;
- class CPerson
- {
- public:
- int m_nAge;
- public:
- CPerson()
- {
- m_nAge = 100;
- }
- public:
- void Show() const
- {
- cout <<m_nAge << endl;
- }
- void Show1()
- {
- m_nAge = 200;
- cout << m_nAge << endl;
- }
- };
- int main()
- {
- const CPerson ps;
- CPerson ps1;
- ps.Show();
- ps1.Show1();
- return 0;
- }
三. 虚函数与多态
1. 引入:
重载: 同名 参数列表不同 调用父类的内容时要加作用域
重写: 同名 参数列表相同 全一致
隐藏: 是纵向重载 只要同名就好
2. 父类的指针指向子类的对象:
例如: CFather* pFather = new CSon;
注意: 这类指针只能看到父类的东西 但是子类的指针不能指向父类的对象
3. 虚函数与多态: 利用父类的复用性 充当接口类
虚函数: virtual
作用: 通过父类的指针调用子类的函数
注意: 虚函数实现多态是基于重写来实现的 这使父类的指针具有多种形态
如果子类中重写了父类的函数 那么在虚函数列表中父类就被子类所覆盖
覆盖基于虚函数的重写 重写在子类中进行重写
- #include<iostream>
- using namespace std;
- class CWater
- {
- public:
- virtual void Show()
- {
- cout <<"CWater::Show()" << endl;
- }
- };
- class CMilk : public CWater
- {
- public:
- void Show()
- {
- cout << "CMilk::Show()" << endl;
- }
- };
- class CBeer : public CWater
- {
- public:
- void Show()
- {
- cout << "CBeer::Show()" << endl;
- }
- };
- void Bottle(CWater* cw)
- {
- cw -> Show();
- }
- int main()
- {
- CMilk cm;
- CBeer cb;
- Bottle(&cm);
- Bottle(&cb);
- return 0;
- }
多态:
用父类的指针指向子类 通过父类的指针调用子类成员函数
- #include<iostream>
- using namespace std;
- class CFather
- {
- public:
- virtual void AA()
- {
- cout <<"CFather::AA()" << endl;
- }
- virtual void BB()
- {
- cout << "CFather::BB()" << endl;
- }
- void CC()
- {
- cout << "CFather::CC()" << endl;
- }
- };
- class CSon : public CFather
- {
- public:
- virtual void AA()
- {
- cout << "CSon::AA()" << endl;
- }
- void CC()
- {
- cout << "CSon::CC()" << endl;
- }
- void DD()
- {
- cout << "CSon::DD()" << endl;
- }
- };
- int main()
- {
- CFather* cf1 = new CSon;
- cf1 -> AA();
- cf1 -> BB();
- cf1 -> CC();
- return 0;
- }
4.(感觉上面整理的好乱) 总结虚函数与多态:
什么是多态:
父类的指针指向一个子类的对象 通过父类的指针调用实际子类的成员函数 这样才会使父类指针具有多种形态
多态基于什么实现:
多态基于虚函数 虚函数基于重写
多态的实现原理: 虚函数列表和虚指针
在虚函数列表中 表中的每个元素都是一个函数指针 指向虚函数 或重写的虚函数
虚函数列表是在编译的时候就存在的 每一个类都有一个 (对于普通的单继承来说)
虚指针就是记录使用哪一个列表的指针 在构造函数中被初始化 指向子类虚函数列表 这个指针是一个类成员
虚指针在创建对象的时候存在 在这个对象的首地址的前 4 个字节就是这个指针
那么我们就可以把调用一个虚函数理解为: 通过虚指针拿到虚函数列表中的函数指针来实现调用的
优缺点:
优点就是提高了复用性 扩展性
缺点就是安全性比较低 空间和效率问题也比较差
最后再放一个典型的例子加深理解: 这段代码的输出足以说明这个问题
- #include<iostream>
- using namespace std;
- class CFather
- {
- public:
- void AA()
- {
- cout <<"CFather::AA()" << endl;
- }
- virtual void BB()
- {
- cout << "CFather::BB()" << endl;
- }
- };
- class CSon : public CFather
- {
- public:
- void AA()
- {
- cout << "CSon::AA()" << endl;
- }
- virtual void BB()
- {
- cout << "CSon::BB()" << endl;
- }
- };
- int main()
- {
- CFather* cf = new CSon;
- cf -> AA();
- cf -> BB();
- CFather* cf1 = new CFather;
- cf1 -> AA();
- cf1 -> BB();
- CSon* cs = new CSon;
- cs -> AA();
- cs -> BB();
- return 0;
- }
5. 调用函数的区别:
调用普通函数 调用哪一个函数 跟指针类型有关
调用虚函数 看当前使用的虚函数列表是哪一个类的
有作用域的话代表已经确定了 作用域的优先级别是最高的
6. 纯虚函数:
格式: virtual void 函数名 () = 0;
注意:
如果一个类包含纯虚函数 那这个类叫抽象类 抽象类是不可以定义对象的
在派生类中一定要实现纯虚函数 那么这个派生类 也叫具体类
如果一个类中的所有函数都是纯虚函数 那么这个类叫接口类
- #include<iostream>
- using namespace std;
- class CPerson
- {
- public:
- virtual void Eat() = 0;
- };
- class CChina : public CPerson
- {
- virtual void Eat()
- {
- cout <<"CChina::Eat()" << endl;
- }
- };
- int main()
- {
- CPerson* cp = new CChina;
- cp -> Eat();
- return 0;
- }
- <C++> 类 (3): 初始化列表 常函数和常量对象 虚函数与多态 (包括纯虚函数)
来源: http://www.bubuko.com/infodetail-2649302.html