zoukankan      html  css  js  c++  java
  • C++中多态实现

    多态 (参考:https://www.cnblogs.com/alinh/p/9636352.html

    概念: 同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。

      对于C++中的多态:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数,如果对象类型是派生类,就调用派生类的函数,如果对象类型是基类,就调用基类的函数。

    重写与重载: 

    重写——指派生类中存在重新定义的函数。其函数名,参数列表,返回值类型,所有都必须同基类中被重写的函数一致。只有函数体不同(花括号内),派生类调用时会调用派生类的重写函数,不会调用被重写函数。重写的基类中被重写的函数必须有virtual修饰。

    重载——指同一可访问区内被声明的几个具有不同参数列(参数的类型,个数,顺序不同)的同名函数,根据参数列表确定调用哪个函数,重载不关心函数返回类型。

    实现多态的方法

    1. C++中通过重载函数的方法可以在编译期间实现多态。

    int Add(int left, int right){
        return left + right;}
    double Add(double left, int right){
        return left + right;}
    int main(){
        Add(10, 20);
        Add(10.0,20);  //正常代码
        return 0;}
    

    2.使用虚函数实现多态

    #include "stdafx.h"
    #include <iostream>
    #include <stdlib.h>
    using namespace std;
    class Father
    {
    public:
        void Face()
        {
            cout << "Father's face" << endl;
        }
        virtual void Say()  // 虚函数
        {
            cout << "Father say hello" << endl;
        }
    };
    class Son:public Father
    {
    public:    
        void Say()
        {
            cout << "Son say hello" << endl;
        }
    };
    void main()
    {
        Son son;
        Father *pFather=&son; // 隐式类型转换
        pFather->Say(); // Son say hello
    }  

    再举一个碰到的题目为例:

    using namespace std;
    class A{
        public:
            virtual void f() { cout << "A::f() "; }
            void f() const { cout << "A::f() const "; }
    };
    class B : public A {
        public:
            void f() { cout << "B::f() "; }
            void f() const { cout << "B::f() const "; }
    };
    void g(const A* a) {
        a->f();
    }
    int main(int argc, char *argv[]) {
        A* p = new B();
        p->f();
        g(p);
        delete(p);
        return 0;
    }

    问: 上面程序的输出是?

     B::f() A::f() const
    

    解释:

      常量指针指向常对象, 常对象只能调用其常成员函数,因此通过g(const A* a)调用的是void f() const;
      由于f()在基类中声明为虚的,则p->f()根据对象类型(B)调用B::f(),此时编译器对虚方法使用动态联编(多态),输出B::f()。
      由于f() const在基类中未声明为虚的,故p->f() const 根据指针类型(A)调用A::f() const,此时编译器对非虚方法使用静态联编,输出A::f() const。
     
  • 相关阅读:
    关于slot标签的使用
    vue组件
    template和component的理解(待更正)
    input 的属性autocomplete
    关于render: h => h(App)和components: { App }的区别
    关于vue的简单知识
    获取页面跳转携带的参数
    关于跨域的简单想法(此想法是错误的,特此备注)
    关于jq建立类似与双向绑定的函数
    关于jq将一个页面引入另一个页面,类似与组件化的解决方案
  • 原文地址:https://www.cnblogs.com/E-Dreamer-Blogs/p/12899556.html
Copyright © 2011-2022 走看看