- #include
- #include
- using namespace std;
- class Animal
- {
- public:
- int m_Age;
- };
- class Sheep : public Animal {};
- class Tuo : public Animal {};
- class SheepTuo :public Sheep, public Tuo
- {
- public:
-
-
- };
-
- void test()
- {
- SheepTuo st;
-
- st.Sheep::m_Age = 100;
- st.Tuo::m_Age = 200;
- cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
- cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
- cout << "st.m_Age = " << st.m_Age << endl;//err
-
- }
- void main()
- {
-
- test();
-
-
- }
![]()
解决菱形继承的问题
- #include
- #include
- using namespace std;
- class Animal
- {
- public:
- int m_Age;
- };
- class Sheep :virtual public Animal {};
- class Tuo :virtual public Animal {};
- class SheepTuo :public Sheep, public Tuo
- {
- public:
-
- };
-
- void test()
- {
- SheepTuo st;
- st.Sheep::m_Age = 100;
- st.Tuo::m_Age = 200;
- cout << "st.Sheep::m_Age = " << st.Sheep::m_Age << endl;
- cout << "st.Tuo::m_Age = " << st.Tuo::m_Age << endl;
- cout << "st.m_Age = " << st.m_Age << endl;//err
-
- }
- void main()
- {
-
- test();
-
-
- }

多态的分类
1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
2、动态多态:派生类和虚函数实现运行时多态
静态多态与动态多态的区别:
1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
继承,编译阶段即确定调用的函数
- #include <iostream>
- #include <string.h>
- using namespace std;
- //多态的分类
- //1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
- //2、动态多态:派生类和虚函数实现运行时多态
- //
- // 静态多态与动态多态的区别:
- //1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
- //2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
- //
- class Animal
- {
- //这里是地址早绑定,静态绑定
- public:
- void speak()
- {
- cout << "Animal speak" << endl;
- }
- };
- class Cat :public Animal
- {
-
- public:
- void speak()
- {
- cout << "Cat speak" << endl;
- }
- };
- class Dog :public Animal
- {
- public:
- void speak()
- {
- cout << "Dog speak" << endl;
- }
- };
- //无论传入的是cat对象还是dog对象,执行的都是Animal的speak方法,这里是地址早绑定,静态绑定
- //编译阶段就确定了调用方法
- void doSpeak(Animal& animal)
- {
- animal.speak();
- }
- void test()
- {
- Cat cat;
- Dog dog;
- doSpeak(dog);
-
- }
-
- void main()
- {
- test();
-
-
- }

利用virtual,虚函数的概念,动态绑定调用的函数
- #include
- #include
- using namespace std;
- //多态的分类
- //1、静态多态:函数重载与运算符重载(本质可以裂解为函数重载)都属于静态多态,复用函数名
- //2、动态多态:派生类和虚函数实现运行时多态
- //
- // 静态多态与动态多态的区别:
- //1、静态多态的函数地址早绑定 - 编译阶段确定函数地址
- //2、动态多态的函数地址晚绑定 - 运行阶段确定函数地址(利用virtual关键字)
- //
- class Animal
- {
- //这里是地址早绑定,静态绑定
- public:
- virtual void speak()
- {
- cout << "Animal speak" << endl;
- }
- };
- class Cat :public Animal
- {
-
- public:
- //这里子类(派生类)的virtual可以省略 override表示复写积累中的方法
- virtual void speak() override
- {
- cout << "Cat speak" << endl;
- }
- };
- class Dog :public Animal
- {
- public:
- void speak()
- {
- cout << "Dog speak" << endl;
- }
- };
- //根据传入的对象cat对象还是dog对象,来决定执行的都是Cat的speak方法,还是Dog的speak方法
- //这里是函数地址晚绑定,动态绑定
- //运行阶段确定调用方法
- void doSpeak(Animal& animal)
- {
- animal.speak();
- }
- void test()
- {
- Cat cat;
- Dog dog;
- doSpeak(dog);
-
- }
-
- void main()
- {
- test();
-
-
- }

下图中的vfprt都是同一个指针,子类会继承父类的虚函数指针与虚函数表,如果发生了子类覆写了父类的virtual的方法,则会子类中的虚函数表的方法会替换成子类的方法指针