虚函数调用的几种方式

Posted 云水

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了虚函数调用的几种方式相关的知识,希望对你有一定的参考价值。

 虚函数调用的几种方式

 

/*
 * 虚函数的三种调用
 * 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;
}

 

运行结果:

 

以上是关于虚函数调用的几种方式的主要内容,如果未能解决你的问题,请参考以下文章

a标签调用js的几种方法

Go 的几种函数参数传递方式

JavaScript 学习-7.函数定义的几种方式

函数调用的几种方式

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式

一张图,理顺 Spring Boot应用在启动阶段执行代码的几种方式