zoukankan      html  css  js  c++  java
  • C++学习笔记27,虚函数作品

    C++它指定虚函数的行为,但实现的作者编译器.

    通常,编译器处理虚函数的方法是给每个对象加入一个隐藏成员.隐藏成员中保存了一个指向函数地址数组的指针.

    这个数组称为虚函数表(virtual function table,vtbl).虚函数表中存储了为类对象进行声明的虚函数的地址.

    比如:基类对象包括一个指针,该指针指向基类的虚函数表.

    派生类对象包括一个指针,该指针指向一个独立的虚函数表.假设派生类提供了虚函数的新定义,虚函数表将保存新的函数地址.

    假设派生类没有又一次定义虚函数,虚函数表将保存原版本号的地址.假设派生类定义了新的虚函数,则将该函数地址也加入到虚函数表中!

    看以下的样例:

    #include <iostream>
    #include <string>
    using namespace std;
    class Animal{
    protected:
    	string name;
    public:
    	Animal(const string &s):name(s){
    	}
    	virtual ~Animal(){
    	}
    	//非虚函数
    	void eat()const{
    		cout<<"Animal eat!"<<endl;
    	}	
    	//不被重写的虚函数
     	virtual void run()const{
    		cout<<"Animal run!"<<endl;
    	}
    
    	//会被重写的虚函数
    	virtual void speak()const{
    		cout<<"I'm a Animal!"<<endl;
    	}
    };
    class Dog:public Animal{
    public:
    	Dog(const string &s):Animal(s){
    	}
    	virtual ~Dog(){
    	}
    	//新定义的函数eat,将掩盖旧的版本号,非重写(重写是指重写virtual函数)
    	void eat()const{
    		cout<<"Dog eat!"<<endl;
    	}
    	//重写speak()
    	virtual void speak()const override{
    		cout<<"This's a Dog!"<<endl;
    	}
    	//新的虚函数
    	virtual void fun1()const{
    	}
    };
    int main(){
    	Animal a("AnimalOne");
    	Dog d1("DogOne");
    
    	Animal *p1=&a;
    	Animal *p2=&d1;
    	p1->speak();	
    	p2->speak();	
    	p1->eat();
    	p2->eat();	//call Animal::eat()
    	p1->run();
    	p2->run();	//call Animal::run()
    	
    	Animal &r1=a;
    	Animal &r2=d1;
    	r1.speak();
    	r2.speak();
    	r1.eat();
    	r2.eat();
    	r1.run();
    	r2.run();
    	
    	return 0;
    
    }
    




    注意eat不是虚函数,不会保存在虚函数表中

    //Animal虚函数表 地址:1000 

    Animal::run()        4000  

    Animal::speak()                  5000
    Dog虚函数表  
    地址:2000

    Dog::run()        4000(没有被重写,保存原地址)

    Dog::speak()   7000(重写了,保存新地址)

    Dog::fun() 8000(新的虚函数,保存地址)

    具体分析以下的代码
    p1->speak(); //找到Animal中speak的地址,5000
    p2->speak(); //找到Dog中speak的地址,7000,运行代码Dog::speak();
    p1->run(); //同上
    p2->run(); //
    这样,对于虚函数表就有了一的初步认识
    !


    
        
            

    版权声明:本文博客原创文章。博客,未经同意,不得转载。

  • 相关阅读:
    typescript 箭头表达式
    typescript 参数类型
    ts介绍
    pm2
    koa2安装
    linux 搭建ftp
    CENTOS6.5 安装 mysql5.6 以及搭建双主
    bzoj 3043 (差分序列运用)
    poj 3277 City Horizon
    NOI2015 程序自动分析
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4636206.html
Copyright © 2011-2022 走看看