虚函数(1)

一、C++为什么引入虚函数,虚函数有哪些用途?

       1.非虚的世界

           对象的自恰性:对同样的函数调用,每个对象都会做出恰当的响应.

                b. 通过指向子类对象的基类指针调用函数:

                 只能调用基类的成员函数,虽然指针指向子类对象.

                 一旦调用子类所特有的成员函数,将引发编译错误.

                c.通过指向基类对象的子真调用函数:

                   可以调用子类的成员函数,尽管指针指向基类对象.

                   直接或简介地访问子类的成员变量,后果不可预知

                 d.名字隐藏

                     子类的成员函数隐藏基类的同名的成员函数.

                  

#include <iostream>
#include <string>
using namespace std;
class Base
{
public:
    Base(int data = 0):m_data(data){}
    void print(void) const 
    {
        cout << m_data << endl;
    }
private:
    int m_data;
};
class Derived:public Base 
{
public:
    Derived(int data,const string& info):
        Base(data),m_info(info){}
    void show(void) const 
    {
        print();
        cout << m_info << endl;
    }
    void foo(void)
    {
        cout << "Derived::foo(void)" << endl;
    //    m_info = "abc";
    }
private:
    string m_info;
};

int main(void)
{
    Base b(100);
    Derived *pd = static_cast<Derived*>(&b); /*子类的指针指向父类*/
    /*pd->show();*/ /*这里可以成功调用但是调用的结果是未定义的
                  因为编译器在调用的时候只看类型.
                 */
    pd = NULL;
    pd->foo();  //这里是可以的,因为编译器在编译的时候只看类型.
    ((Derived*)0)->foo();
    /*函数并不存在于对象中,调用成员函数的时候,
     只要调用的类型是对的,就可以根据类型调用相应的
     成员函数.但是这种情况之下不能访问成员变量*/
    return 0;
}

2. 虚函数和名字隐藏

    class 类名

    {

       virtual 返回类型 函数名(形参表){...}

    }

    的成员函数,称为虚函数或方法

    覆盖:

    如果子类的成员函数和基类的虚函数具有相同的函数原型,那么该成员

    函数就也是虚函数,无论其是否有virtual关键字,且对基类的虚函数

    构成覆盖.

    还有一种就是如果没有virtual的时候,只要函数名相同就会形成覆盖.

3.多态

    如果子类提供了对基类虚函数的有效覆盖,那么通过一个指向子类对象的基类指针,

     或者引用子类对象的基类引用,调用该虚函数,实际被调用的将是子类中覆盖

     版本,而非基类中的原始,这种现象称之为多态.

     多态的重要意义在于,一般的情况下,调用哪个类的成员函数是由调用者指针或引用

     本身的类型决定的,而当多态发生的时候,调用哪个类的成员函数则

     完全由调动者指针或引用的实际目标对象的类型决定的.

  4.有效的虚函数的覆盖要满足如下的条件

      该函数必须是成员函数,既不能是全局函数也不能是静态成员函数.

      该函数必须在基类中用vitual关键字声明为虚函数

      覆盖版本与基类版本必须拥有完全相同的签名,即是函数名,行参表和常属性严格一致.

      如果基类版本返回基本数据类型,那么覆盖版本必须返回相同的类型的数据.

      如果基类版本返回类类型对象的指针或引用,那么覆盖版本可以返回

      其子类类型对象的指针或引用.

 

原文地址:https://www.cnblogs.com/yasanlun/p/3856141.html