【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“

06-02 1557阅读

欢迎来到一整颗红豆的博客✨,一个关于探索技术的角落,记录学习的点滴📖,分享实用的技巧🛠️,偶尔还有一些奇思妙想💡

本文由一整颗红豆原创✍️,感谢支持❤️!请尊重原创📩!欢迎评论区留言交流🌟

个人主页 👉 一整颗红豆

本文专栏 ➡️C++ 进阶之路

【C++ 多态】—— 礼器九鼎,釉下乾坤,多态中的 “风水寻龙诀“

礼器九鼎,釉下乾坤,多态中的 "风水寻龙诀"

  • 多态的概念
    • 编译时多态(静态多态)
      • `编译时多态的实现方式有,函数重载,运算符重载和模板。`
      • 函数重载 `Function Overloading`
      • 运算符重载(`Operator Overloading`)
      • 模板(`Templates`)
      • 编译时多态的特点
        • 静态绑定(`Static Binding`)
        • 类型安全(`Type Safety`)
        • 无运行时开销
        • 代码膨胀(`Code bloat`)
        • 运行时多态(动态多态)
          • 认识虚函数(`Virtual function`)
          • 虚函数的重写/覆盖(`override`和`final`)
          • 纯虚函数(`Pure Virtual Function`)和抽象类
          • 虚析构函数(`Virtual Destructor`)
          • 协变(`Covariant Return Types`)
          • 重载(`Overload`)、重写(`Override`)、隐藏(`Hide`)的对比
            • 重载(`Overload`)
            • 重写(`Override`)
            • 隐藏(`Hide`)
            • 多态的原理
              • 虚函数表(`vtable`)
                • 虚函数表的概念
                • 虚函数表的生成规则
                • 多态是如何实现的
                  • 动态绑定和静态绑定
                  • 虚函数表的位置
                  • 总结多态调用
                  • 写在最后

                    多态的概念

                    众所周知,面向对象有三大特性,封装、继承和多态!

                    多态(Polymorphism) 是面向对象编程的核心特性,允许用统一的接口操作不同类型的对象,并根据对象实际类型执行不同的行为。C++中的多态分为编译时多态和运行时多态。

                    编译时多态(静态多态)

                    编译时多态(Compile-Time Polymorphism) 又称为 静态多态,是一种在 代码编译阶段就能确定具体调用行为的机制。它的核心特点是 基于静态类型系统,通过代码结构直接决定调用哪个函数或操作,无需运行时动态查找。

                    编译时多态的实现方式有,函数重载,运算符重载和模板。


                    函数重载 Function Overloading

                    • 通过 参数列表不同(类型/数量/顺序)定义同名函数

                      示例:

                      void print(int x)
                      {
                          std::cout 
                          std::cout 
                          std::cout 
                          print(10);      // 调用 print(int)
                          print(3.14);    // 调用 print(double)
                          print("Hello"); // 调用 print(const char*)
                      }
                      
                      private:
                          double real;
                          double imag;
                      public:
                          Complex(double r = 0, double i = 0) : real(r), imag(i) {}
                          // 重载 + 运算符
                          Complex operator+(const Complex &other)
                          {
                              return Complex(real + other.real, imag + other.imag);
                          }
                          void print()
                          {
                              std::cout 
                          // 运算符重载调用
                          Complex c1(1, 2);
                          Complex c2(3, 4);
                          Complex c3 = c1 + c2;
                          std::cout 
                          return (a  b) ? a : b;
                      }
                      
                          std::cout 
                      public:
                          void push(const T &item) { _elements.push_back(item); }
                          T pop() {}
                      private:
                          std::vector
                          Stack
                          add(3, 5);     // 编译时直接绑定到函数A
                          add(3.0, 5.0); // 编译时直接绑定到函数B
                          return 0;
                      }
                       return (a  b) ? a : b; }
                      int main()
                      {
                          Max(3, 5.0); // 编译出错:T 同时推导为 int 和 double,类型不一致
                          return 0;
                      }
                       return x * x; }
                      int main()
                      {
                          square(5);    // 生成 int square(int x) { return x*x; }
                          square(3.14); // 生成 double square(double x) { return x*x; }
                          return 0;
                      }
                      
                          T data; /*...*/
                      };
                      int main()
                      {
                          Wrapper
                      public:
                          virtual void speak()
                          { // 使用 virtual 关键字
                              std::cout 
                      public:
                          void speak() override
                          { // 使用 override 明确重写(C++11)
                              std::cout 
                          Animal *animal = new Dog();
                          animal-speak(); // 输出 "Woof!"(调用 Dog 的实现)
                          delete animal;
                          return 0;
                      }
                      
                      public:
                          virtual void func(int) {}
                      };
                      class Derived : public Base {
                      public:
                          void func(double) {} // 参数类型不一致,未覆盖基类 func(int)
                      };
                      
                      public:
                          void func(int) override {} // 使用 override 强制编译器检查覆盖
                      };
                      
                      public:
                          void func() {} // 非虚函数
                      };
                      class Derived : public Base {
                      public:
                          void func() {} // 隐藏基类函数,无法多态调用
                      };
                      
                      public:
                          virtual void Drive() final {}
                      };
                      class Benz : public Car
                      {
                      public:
                          virtual void Drive()
                          {
                              std::cout 
                      public:
                          virtual void func(int val = 1) { std::cout  func(); }
                      };
                      class B : public A
                      {
                      public:
                          void func(int val = 0) { std::cout 
                          B *p = new B;
                          p-test();
                          return 0;
                      }
                      
                      public:
                          virtual void sound() const = 0; // 纯虚函数
                          virtual ~Animal() {}            // 虚析构函数(重要!)
                      };
                      // 派生类必须实现 sound()
                      class Dog : public Animal
                      {
                      public:
                          void sound() const override
                          { // 重写纯虚函数
                              std::cout 
                      public:
                          void sound() const override
                          { // 重写纯虚函数
                              std::cout 
                      public:
                          virtual void sound() const = 0;
                      };
                      // 纯虚函数的默认实现(罕见用法)必须实在类外实现的!
                      void Animal::sound() const
                      {
                          std::cout 
                      public:
                          void sound() const override
                          {
                              Animal::sound(); // 调用基类的默认实现
                              std::cout  // 基类(无虚析构函数)
                      public:
                          ~Base()
                          {
                              std::cout  // 派生类(持有动态资源)
                      public:
                          int *data;
                          Derived()
                          {
                              data = new int[100]; // 动态分配内存
                          }
                          ~Derived()
                          {
                              delete[] data; // 释放内存
                              std::cout 
                          Base *obj = new Derived(); // 基类指针指向派生类对象
                          delete obj;                // 仅调用了Base基类的析构函数
                          return 0;
                      }
                      
                      public:
                          virtual ~Base()
                          { // 声明为虚析构函数
                              std::cout 
                      public:
                          ~Derived() override
                          { // 重写虚析构函数
                              std::cout 
                          Base *obj = new Derived();
                          delete obj; // 正确调用Derived和Base的析构函数
                          return 0;
                      }
                      
                      public:
                          virtual Fruit* clone() const {   // 虚函数,返回Fruit*(基类指针)
                              return new Fruit(*this);
                          }
                          virtual ~Fruit() {}
                      };
                      // 派生类
                      class Apple : public Fruit {
                      public:
                          Apple* clone() const override {  // 协变:返回Apple*(派生类指针)
                              return new Apple(*this);
                          }
                          
                          void sayName() const {
                              std::cout 
                          Fruit* fruit = new Apple();      // 基类指针指向派生类对象
                          Fruit* cloned = fruit-clone();  // 调用派生类的clone()
                          // 验证协变特性
                          if (Apple* apple = dynamic_cast
                              apple-sayName();  // 成功调用Apple特有方法
                          } else {
                              std::cout 
                      public:
                          // 重载示例
                          int add(int a, int b) { return a + b; }
                          double add(double a, double b) { return a + b; }  // 参数类型不同
                          int add(int a, int b, int c) { return a + b + c; } // 参数数量不同
                      };
                      
                      public:
                          void func() { std::cout  std::cout 
                      public:
                          // 隐藏基类的所有 func 函数(包括重载)
                          void func() { std::cout 
                          Derived d;
                          d.func();     // 正确:调用 Derived::func()
                          // d.func(1); // 错误!Base::func(int) 被隐藏
                          d.Base::func(1); // 正确:显式调用基类函数
                          return 0;
                      }
                      
                      public:
                          virtual void Func1()
                          {
                              std::cout 
                          Base b;
                          std::cout 
                      public:
                          virtual void func1() {}
                          virtual void func2() {}
                          int data;
                      };
                      
                      public:
                          void func1() override {}  // 重写基类的func1
                          virtual void func3() {}   // 新增虚函数
                      };
                       virtual void f1(); };
                      class Base2 { virtual void f2(); };
                      class Derived : public Base1, public Base2 {
                          void f1() override {}
                          void f2() override {}
                      };
                      
                      public:
                          void nonVirtualFunc() { std::cout 
                      public:
                          void nonVirtualFunc() { std::cout 
                          Base* obj = new Derived();
                          obj-nonVirtualFunc();  // 输出 "Base"(静态绑定)
                          delete obj;
                          return 0;
                      }
                       /* ... */ }
                      func();  // 静态绑定
                       /* ... */ }
                      templateFunc(42);  // 编译时生成针对int的版本
                      
                      public:
                          virtual void virtualFunc() { std::cout 
                      public:
                          void virtualFunc() override { std::cout 
                          Base* obj = new Derived();
                          obj-virtualFunc();  // 输出 "Derived"(动态绑定)
                          delete obj;
                          return 0;
                      }
                      
                      public:
                          virtual ~Base() {}  // 虚析构函数
                      };
                      class Derived : public Base {
                      public:
                          ~Derived() override { /* 释放派生类资源 */ }
                      };
                      Base* obj = new Derived();
                      delete obj;  // 动态调用~Derived()
                      
                      public:
                          virtual void func(int val = 1) { std::cout  func(); }
                      };
                      class B : public A
                      {
                      public:
                          void func(int val = 0) { std::cout 
                          B *p = new B;
                          p-test();
                          return 0;
                      }
                      
                      public:
                          virtual void func1() { cout  cout  cout 
                      public:
                          // 重写基类的func1
                          virtual void func1() { cout  cout  cout 
                          int i = 0;
                          static int j = 1;
                          int *p1 = new int;
                          const char *p2 = "xxxxxxxx";
                          printf("栈:%p\n", &i);
                          printf("静态区:%p\n", &j);
                          printf("堆:%p\n", p1);
                          printf("常量区:%p\n", p2);
                          Base b;
                          Derive d;
                          Base *p3 = &b;
                          Derive *p4 = &d;
                          printf("Person虚表地址:%p\n", *(int *)p3);
                          printf("Student虚表地址:%p\n", *(int *)p4);
                          printf("虚函数地址:%p\n", &Base::func1);
                          printf("普通函数地址:%p\n", &Base::func5);
                          return 0;
                      }
                      
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码