C++:多态讲解

慈云数据 2024-03-13 技术支持 57 0

多态

    • 1.多态的概念
    • 2.多态的定义和实现
      • 2.1多态构成条件
      • 2.2虚函数
      • 2.3虚函数的重写(覆盖)
      • 2.4 C++11 override 和 final
      • 2.5重载、重写(覆盖)、隐藏(重定义)的对比
      • 3.抽象
      • 4.多态的原理
      • 5.单继承和多继承关系的虚函数表
        • 5.1单继承
        • 5.2多继承
        • 5.3菱形继承和多态

          1.多态的概念

          多态的概念:同样的一个行为,不同的对象去完成时会产生不同的状态。

          例子:拿买票举例,军人、学生、普通人(子类)都是人(父类),但军人买票可以优选选票,学生买票可以半价,普通人买票就要全价了。因此要实现多态必先继承。



          2.多态的定义和实现

          2.1多态构成条件

          多态是在不同继承关系的类对象,去调用同一函数,产生了不同的行为。比如上面的例子定义父类Person,让子类Student继承Preson。Person对象买票全价,Student对象买票半价。

          已经形成了继承关系,实现多态还需要以下两个条件:

          1. 必须通过基类的指针或者引用调用虚函数
          2. 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写

          大家先记住这两个条件,后面讲解虚函数和多态原理后大家就明白了。

          2.2虚函数

          虚函数:即被virtual修饰的类成员函数称为虚函数。

          class Person {
          public:
          	//这里和菱形虚拟继承公用了关键字,但两者是没有关联的
          	virtual void BuyTicket() { cout 
          public:
          	virtual void BuyTicket() { cout 
          public:
          	virtual void BuyTicket() { cout 
          	p.BuyTicket();  //因为是父类引用去调用,所以构成多态
          }
          int main()
          {
          	Person ps;
          	Student st;
          	Func(ps);
          	Func(st);
          	return 0;
          }
          };
          class B : public A {};
          class Person {
          public:
           virtual A* f() {return new A;}
          };
          class Student : public Person {
          public:
           virtual B* f() {return new B;}
          };
          
          public:
          	virtual ~Person() { cout 
          public:
          	virtual ~Student() { cout 
          	Person* p1 = new Person;
          	Person* p2 = new Student;  //如果父类析构不设计为虚函数的话可能造成内存泄漏
          	delete p1;
          	delete p2;
          	return 0;
          }
          
          public:
          	virtual void Drive() final {}
          };
          class Benz :public Car
          {
          public:
          	virtual void Drive() { cout 
          	//……
          };
          class B : public A  //这里会报错
          {};
          
          public:
          	virtual void Drive() {}
          };
          class Benz :public Car {
          public:
          	virtual void Drive() override { cout }
          void fun(double a)
          {}
          //隐藏
          //两个同名函数在基类和派生类作用域内,不构成重写就属于隐藏
          class A
          {
          	void fun(int a)
          	{}
          };
          class B : public A
          {
          	void fun(int a)
          	{}
          };
          //重写
          //两个同名函数在基类和派生类作用域内,并且都是虚函数
          //函数名、参数列表、返回值都必须一致(除去例外),才能构成重写
          class C
          {
          	virtual void fun(int a)
          	{}
          };
          class D : public C
          {
          	virtual void fun(int a)
          	{}
          };
          
          public:
          	virtual double GetArea() = 0
          	{}//抽象类里面可以设计图形共有的接口,比如求面积等
          };
          class Square : public Graphics  //正方形
          {
          public:
          	virtual double GetArea()
          	{
          		return side_length * side_length;
          	}
          private:
          	int side_length = 5;
          };
          class rotundity : public Graphics  //圆形
          {
          public:
          	virtual double GetArea()
          	{
          		return 3.14 * radius * radius;
          	}
          private:
          	int radius = 5;
          };
          int main()
          {
          	Square sq;
          	rotundity ro;
          	cout 
          public:
          	virtual void Func1()
          	{
          		cout 
          public:
          	virtual void BuyTicket() { cout 
          public:
          	virtual void BuyTicket() { cout 
          	p.BuyTicket();
          }
          int main()
          {
          	Person Mike;
          	Func(Mike);
          	Student Johnson;
          	Func(Johnson);
          	//这里不构成多态,对象调用而不是指针或引用,按正常调用规则即可
          	Mike.BuyTicket();  
          	return 0;
          }
          
          public:
          	virtual void fun(int a)
          	{}
          };
          class B
          {
          public:
          	virtual void fun(int b)
          	{}
          };
          class C : public A, public B  //继承A、B两个类
          {
          public:
          	virtual void fun(int c)
          	{}
          };
          int main()
          {
          	C c;
          	A* p1 = new C;
          	B* p2 = new C;
          	p1-fun();
          	p2-fun();
          	delete p1, p1 = nullptr;
          	delete p2, p2 = nullptr;
          	return 0;
          }
          
微信扫一扫加客服

微信扫一扫加客服

点击启动AI问答
Draggable Icon