zoukankan      html  css  js  c++  java
  • 虚函数调用的几种方式

     虚函数调用的几种方式

    /*
     * 虚函数的三种调用
     * 1: 指针
     * 2: 引用
     * 3: 对象(不能实现多态)
     */
    
    #include <iostream>
    
    
    //继承,默认情况下class是私有继承 struct默认是公有继承
    //虚函数可以调用成员函数
    //多态调用依赖于指针 或 引用调用
    //对象的调用有副本机制,会调用拷贝构造 拷贝一个父类 无法实现多态
    //p->go();   //多态调用
    //p->myclass::go();  //原生调用
    //虚函数重载和返回值无关 和参数的类型 个数 顺序有关
    //虚函数被继承下来了还是虚函数
    //如果要使用被继承的虚函数 不允许出现虚函数重载和覆盖
    //多态可以跨类 爷爷辈的指针 可以存储孙子辈的地址 父辈拔针的地址 
    class myclass
    {
    public:
        int i;
        virtual void go()
        {
            i = 0;
            show();
        }
        void show()
        {
            std::cout << "myclass->show()" << std::endl;
        }
        virtual ~myclass()
        {
            // 不加virtual 会造成内存泄漏
        }
    };
    
    class newmyclass: public myclass
    {
    public:
        void go()
        {
            std::cout << "newmyclass->go()" << std::endl;
        }
        void show()
        {
            std::cout << "newmyclass->show()" << std::endl;
        }
        void put()
        {
            std::cout << "newmyclass->put()" << std::endl;
        }
    };
    
    // 1: 指针
    void test1(myclass *p)
    {
        p->go();
    }
    
    // 2: 引用
    void test2(myclass &p)
    {
        p.go();
    }
    
    // 3: 对象
    void test3(myclass my)
    {
        my.go();
    }
    
    int main()
    {
        myclass my;
        my.go(); // 正常调用父类的go函数
    
        newmyclass newmy;
        newmy.go(); // 正常调用子类的go函数
    
        myclass *pmy(nullptr);
        pmy->show(); // 空指针可以调用show操作
        //pmy->go(); // 空指针无法调用go函数,因为myclass类,没有实例化为对象,go函数内部操作了对象的内部变量,此时该内部变量并没有构造出来
    
        myclass *p = new newmyclass;
        p->go(); // 调用子类的go函数
        p->myclass::go(); // 指定调用父类的go函数
        std::cout << typeid(p).name() << std::endl; // p的类型为父类类型指针 class myclass *
        std::cout << typeid(*p).name() << std::endl; // *p的类型为子类类型 class newmyclass
    
        test1(p); // 调用子类的go函数
        test1(&my); // 调用父类的go函数
        test1(&newmy); // 调用子类的go函数
    
        // 引用在语言内部用指针实现,引用是操作受限了的指针(仅容许取内容操作)
        test2(*p);  // 调用子类的go函数
        test2(my); // 调用父类的go函数
        test2(newmy); // 调用子类的go函数
    
        // 对象作为参数,会使用拷贝构造函数,形成对象的副本
        test3(*p); // 调用父类的go函数
        test3(my); // 调用父类的go函数
        test3(newmy); // 调用父类的go函数
    
        //std::cout << "mytest" << std::endl;
        system("pause");
        return 0;
    }

    运行结果:

  • 相关阅读:
    【翻译】让你的网站飞起来
    理解ASP.NET MVC中的模型绑定
    【转载】创建定制ASP.NET MVC视图引擎
    修改STM32主频
    Cortex系列ARM核心及体系结构介绍
    递归
    NFD模拟兴趣包的转发
    NX 笔记
    MicroPython 8266 配置
    Python JSON操作
  • 原文地址:https://www.cnblogs.com/lsgxeva/p/7692567.html
Copyright © 2011-2022 走看看