zoukankan      html  css  js  c++  java
  • C++ 虚函数、纯虚函数、虚继承

    1)C++利用虚函数来实现多态。

    程序执行时的多态性通过虚函数体现,实现运行时多态性的机制称爲动态绑定;与编译时的多态性(通过函数重载、运算符重载体现,称爲静态绑定)相对应。

    在成员函数的声明前加上virtual修饰,派生类可以不加virtual修饰,则声明之为虚函数。在派生类中可以重新定义从基类继承下来的虚函数。下面是一个例子,Rectangle是Shape的派生类,在类Rectangle中对Shape中的虚函数Draw()进行了重新定义:

    class Shape { 
    
      public:
    
      virtual void Draw() { }
    
    };
    
    class Rectangle : public Shape { 
    
      public:
    
      virtual void Draw() { }
    
    };

    类Rectangle中的Draw()函数前面的virtual可不加,那麽它就不再可以被它的继承类重新定义。

    虚函数的调用

    要想调用一个在派生类中重定义的函数,必须使用多态调用,它必须使用指针来实现。下面是一个典型的例子:

    void fun1(Shape s) { s.Draw(); } //非多态
    
    void fun2(Shape &s) { s.Draw(); } //多态
    
    void fun3(Shape *s) { s->Draw(); } //多态
    
    int main()
    
    { 
    
      Rectangle rr;
    
      fun1(rr); //调用类Shape的Draw()
    
      fun2(rr); //调用类Rectangle的Draw()
    
      fun3(&rr); //调用类Rectangle的Draw()
    
    }

    只有使用指针和引用调用时,才能进行多态调用。

    2)技巧:虚函数的调用地址只看对象声明时的类名(看后面),普通函数的调用地址看对象定义时的类名(看前面)。

    所以构造函数不能是虚函数,而析构函数最好是虚函数。

    如下:

    #include<iostream>  
    using namespace std;  
      
    class A  
    {  
    public:  
        void foo()  
        {  
            printf("1
    ");  
        }  
        virtual void fun()  
        {  
            printf("2
    ");  
        }  
    };  
    class B : public A  
    {  
    public:  
        void foo()  
        {  
            printf("3
    ");  
        }  
        void fun()  
        {  
            printf("4
    ");  
        }  
    };  
    int main(void)  
    {  
        A a;  
        B b;  
        A *p = &a;  
        p->foo();  //1
        p->fun();  //2
        p = &b;  
        p->foo();  //1,普通函数看前面,调用的就是A类的方法。
        p->fun();  //4,虚函数看后面,调用的是 B类的方法。
        return 0;  
    }  
     B *ptr = (B *)&a;
     ptr->foo();  //3,普通函数看前面,所以调用的是 B类的方法。
     ptr->fun();  //2,虚函数看后面,所以调用的是A类的方法。

    原理可以看这篇文章:

    C++虚函数与虚函数表

    3)纯虚函数

    纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0” 

      virtual void funtion()=0 

    类似于java里的interface,派生类必须要实现它。

    4)虚继承

    参考:c++ 虚继承详解  http://blog.163.com/redhumor@126/blog/static/19554784201131174216260/

      

  • 相关阅读:
    excel数据导入mySql数据库
    springboot-devtools实现项目的自动重启
    Java中List, Integer[], int[]的相互转换
    Postman代码测试工具如何用?
    git提交代码时,Unstaged changes如何过滤.class .log等文件
    Json字符串转map集合
    实现hibernate 的validator校验
    [转载]OpenSSL中文手册之命令行详解(未完待续)
    Openssl ASN.1 说明一 分享
    [转载]Parsing X.509 Certificates with OpenSSL and C
  • 原文地址:https://www.cnblogs.com/wliangde/p/3681800.html
Copyright © 2011-2022 走看看