zoukankan      html  css  js  c++  java
  • C++虚函数

        C++虚函数工作原理:声明虚函数的类中会有一个隐藏变量(所以会多4个字节),主要指向虚函数地址的表。如果子类没有重写父类的虚函数,子类中的虚函数地址表中该虚函数地址跟父类一样,如果重写了父类的虚函数,则该虚函数地址则为新的。如果一个函数没有申明为虚函数,编译器会进行静态联编,如果改行申明为虚函数,编译器则进行动态联编。所以在程序运行时,发现调用的函数是虚函数时,会在对象的虚函数表中查找该函数的地址。

     看以下例子:

    #include<iostream>
    using namespace std;
    class A
    {
    public:
        void Print(){cout<<"A"<<endl;}
    };
    class B:public A
    {
    public:
        void Print(){cout<<"B"<<endl;}
    };
    class C
    {
    public:
        virtual void Print(){cout<<"C"<<endl;}
    };
    class D:public C
    {
    public:
        void Print(){cout<<"D"<<endl;}
    };
    int main()
    {
        B b;
        D d;
        A &a = b;
        a.Print();
        //输出是A,静态联编
        C &c = d;
        c.Print();
        //输出是D,动态联编,通过虚函数表查找函数地址
        return 0;
    }

     一个函数的析构函数最好申明为虚函数,不然很有可能导致资源泄露

    #include<iostream>
    #include<cstdio>
    using namespace std;
    class A
    {
    public:
        A(){cout<<"A"<<endl;}
        ~A(){cout<<"~A"<<endl;}
    };
    class B:public A
    {
    public:
        B(){cout<<"B"<<endl;}
        ~B(){cout<<"~B"<<endl;}
    };
    class C
    {
    public:
        C(){cout<<"C"<<endl;}
        virtual ~C(){cout<<"~C"<<endl;}
    };
    class D:public C
    {
    public:
        D(){cout<<"D"<<endl;}
        ~D(){cout<<"~D"<<endl;}
    };
    int main()
    {
        A *a = new B();
        delete a;
        /*没有调用B的析构
        A
        B
        ~A
        */
        C *c = new D();
        delete c;
        /*
        A
        B
        ~B
        ~A
        */
        return 0;
    }

     C++ 子类写父类的函数叫重写,即使参数不一样或者名字不一样,都叫重写。父类如果有3个函数,void fun(),void fun(int) ,void fun(int,int);子类即使重写了void fun()这一个函数,父类的void fun(int),void fun(int,in)在子类中也被隐藏,所以每次子类重写父类函数时,需要把父类所有重载的函数都要写一遍。

  • 相关阅读:
    结构体
    指针
    数组
    银行取款机系统
    函数
    基础
    IOS系统的安装和Vi的操作模式以及简单的指令
    1203.4——循环语句 之 for
    1203.3——循环语句 之 while
    1203.2——条件语句 之 switch语句
  • 原文地址:https://www.cnblogs.com/jlyg/p/10328578.html
Copyright © 2011-2022 走看看