• C++学习笔记26,虚函数


    在C++里面,虚拟功能是功能的一类重要!不同目的可以通过在不同的虚拟功能来达到同样的动作被定义。

    举一个简单的例子:

    #include <iostream>
    #include <string>
    using namespace std;
    class Animal{
    protected:
    	string name;
    public:
    	Animal(const string &s):name(s){
    	}
    	virtual ~Animal(){
    	}
    	virtual void speak()const{
    		cout<<"I'm a Animal!"<<endl;
    	}
    };
    class Dog:public Animal{
    public:
    	Dog(const string &s):Animal(s){
    	}
    	virtual ~Dog(){
    	}
    	virtual void speak()const override{
    		cout<<"This's a Dog!"<<endl;
    	}
    };
    int main(){
    	Animal a("AnimalOne");
    	Dog d1("DogOne");
    
    
    <span style="white-space:pre">	</span>//用指针调用speak()
    	Animal *p1=&a;
    	Animal *p2=&d1;
    	p1->speak();
    	p2->speak();	
    <span style="white-space:pre">	</span>//用引用调用speak()
    	Animal &r1=a;
    	Animal &r2=d1;
    	r1.speak();
    	r2.speak();
    
    	return 0;
    
    }
    
    结果:


    能够看出,通过指针和引用能够调用相应的虚函数.即便指针和引用都声明为Animal 类型,可是却能够调用相应的函数(Dog::speak()).

    因此,假设须要在派生类中又一次定义基类的方法,应该将该方法设置为虚方法.

    须要注意的是仅仅有指针和引用才干正确引发对应的虚函数.同一时候函数必须声明为虚的.假设不是的话,将仅仅会调用对应的类成员函数.

    比如:

    #include <iostream>
    #include <string>
    using namespace std;
    class Animal{
    protected:
    	string name;
    public:
    	Animal(const string &s):name(s){
    	}
    	virtual ~Animal(){
    	}
    	void speak()const{
    		cout<<"I'm a Animal!"<<endl;
    	}
    };
    class Dog:public Animal{
    public:
    	Dog(const string &s):Animal(s){
    	}
    	virtual ~Dog(){
    	}
    	void speak()const {
    		cout<<"This's a Dog!"<<endl;
    	}
    };
    int main(){
    	Animal a("AnimalOne");
    	Dog d1("DogOne");
    
    	Animal *p1=&a;
    	Animal *p2=&d1;
    	p1->speak();
    	p2->speak();	
    
    	Animal &r1=a;
    	Animal &r2=d1;
    	r1.speak();
    	r2.speak();
    
    	return 0;
    
    }
    
    执行结果:


    假设成员函数不是虚的,就不能达到这种效果.这就是动态绑定.

    再看一个样例:

    #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;
    	}
    };
    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;
    
    }
    

    结果:





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

  • 相关阅读:
    微服务2:微服务全景架构
    SystemVerilog语言简介
    Slip打包与解包及MATLAB程序
    恶性卷积码
    通信原理之调制解调(2)QPSK
    FPGA仿真只适合开发定制IP的设计师?
    用CCS开发DSP应用程序的代码结构、加电装载及在线编程
    符号能量问题
    该如何选择?
    无线通信距离的计算
  • 原文地址:https://www.cnblogs.com/gcczhongduan/p/4725276.html
Copyright © 2020-2023  润新知