zoukankan      html  css  js  c++  java
  • 类成员函数的重载 继承 隐藏

    重载

    1. 相同的范围(在同一个类中)
    2. 函数名相同
    3. 参数不同
    4. virtual关键字可有可无

    重载与继承、隐藏很好区分,因为重载函数在同一个类中

    举例说明

    #include <iostream>
    using namespace std;
    class Base
    {
        public:
            void f(int x) {cout << "Base f(int)" << x << endl;}
            void f(float x) {cout << "Base f(float)" << x << endl;}
    };
    
    int main()
    {
        Base b;
        b.f(42);
        b.f(3.14f);
    }

    结果

     

    继承

    1. 不同的范围(分别位于基类和派生类)
    2. 函数名相同
    3. 参数相同
    4. 基类必须有virtual关键字

    隐藏

    • 如果派生类的函数与基类的函数同名、同参数,基类函数不带有virtual关键字
    • 如果派生类函数与基类的函数同名、不同惨,不管基类函数带不带virtual关键字

    归纳起来

       同名前提(不同名免谈)

    • 同参+virtual——继承
    • 同参+无virtual  / 不同参 —— 隐藏

    强调:只要不是继承(virtural+同参)就是隐藏,隐藏后,如果基类、派生类有相同函数名,派生类对象只能调用派生类的函数。

    #include <iostream>
    #include <string>
    using namespace std;
    
    class base
    {
        public:
            virtual void test(int a, int b) { cout << a << " " << b << endl; }
    };
    class derived : public base
    {
        public:
            void test(int a) { cout << a << endl; } //隐藏
    };
    
    int main()
    {
        derived m;
        m.test(45);
        m.test(4, 5);  //error:派生类中没有俩参数的
    }
    View Code
    #include <iostream>
    #include <string>
    using namespace std;
    
    class base
    {
        public:
            void test(int a, int b) { cout << a << " " << b << endl; }
    };
    class derived : public base
    {
        public:
            void test(int a) { cout << a << endl; } //隐藏
    };
    
    int main()
    {
        derived m;
        m.test(45);
        m.test(4, 5);  //error:派生类中没有俩参数的
    }
    View Code

    举例说明

    #include <iostream>
    using namespace std;
    class Base
    {
        public:
            virtual void f(float x) {cout << "Base f" << x << endl;}
            void g(float x) {cout << "Base g" << x << endl;}
            void h(float x) {cout << "Base h" << x << endl;}
    };
    
    class Derived : public Base
    {
        public:
            void f(float x) {cout << "Derived f" << x << endl;}  //同参 + virtual —— 继承
            void g(int x) {cout << "Derived g" << x << endl;}    //不同惨 ——隐藏
            void h(float x) {cout << "Derived h" << x << endl;}  //同参 + 无virtual ——隐藏
    };
    
    int main()
    {
        Derived d;
        Base *pb = &d;
        Derived *pd = &d;
        
        pb->f(3.14f);
        pd->f(3.14f);
    
        pb->g(3.14f);
        pd->g(3.14f);
        
        pb->h(3.14f);
        pd->h(3.14f);
    }

    结果
     

    举例说明虚函数、隐藏的区别

    #include <iostream>
    #include <string>
    using namespace std;
    
    class base
    {
        public:
            virtual void test() { cout << "test base" << endl; }
            void test_1() { cout << "test_1 base" << endl; }
    };
    
    class derived : public base
    {
        public:
            void test() { cout << "test derived" << endl; }       //虚函数
            void test_1() { cout << "test_1 derived" << endl; }   //隐藏
    };
    
    int main()
    {
        derived d1, d2;
        base *p1 = &d1;
        base *p2 = &d2;
        p1->test();
        p2->test_1();
    }                                

    结果

    分析

          动态绑定必须通过基类的引用指针调用虚函数(virtual)。当这样做时,编译器将在基类中查找virtual函数。

    假如找到了(同名、同参):就在其派生类中找对应的函数(这就是为什么必须在基类和派生类中特点是:同名、同参)。

    • 如果找到了就调用派生类的函数
    • 否则乖乖的用基类的虚函数

    假如没找到对应的virtual,就找对应的函数(同名同参),这回只能在父类中倒腾了,因为根本没法通过virtual穿越到子类。

          隐藏就不同了,如果基类中连函数原型都没有,就直接报错了。如果有:直接调用就得啦(没有virtural没法对应派生类的重定义的函数)。

  • 相关阅读:
    《数据库技术基础与应用(第2版)》学习笔记——第4章
    《数据库技术基础与应用(第2版)》学习笔记——第4章
    《数据库技术基础与应用(第2版)》学习笔记——第3章
    《数据库技术基础与应用(第2版)》学习笔记——第3章
    《数据库技术基础与应用(第2版)》学习笔记——第2章
    《数据库技术基础与应用(第2版)》学习笔记——第2章
    《数据库技术基础与应用(第2版)》学习笔记——第1章
    《数据库技术基础与应用(第2版)》学习笔记——第1章
    新近碰到的病毒(TR.Spy.Babonock.A)
    新近碰到的病毒(TR.Spy.Babonock.A)
  • 原文地址:https://www.cnblogs.com/kaituorensheng/p/3248609.html
Copyright © 2011-2022 走看看