码迷,mamicode.com
首页 > 编程语言 > 详细

C++虚函数与非虚函数的区别。

时间:2019-07-24 11:50:40      阅读:156      评论:0      收藏:0      [点我收藏+]

标签:ati   pac   some   func   ios   names   动态   fast   turn   

#include <iostream> #include <string> /* * Animal 与Dog之间没有虚函数 * Animal Fish有一个eating的虚函数 * 通过"基类的指针" 访问 子类(们)的成员函数。这叫动态多态。是用虚函数的技术完成的。这也叫动态绑定。] * 当我们使用基类的引用(或指针)调用一个虚函数时将发生动态绑定(dynamic binding) 因为我们直到运行时才能知道到底调用了哪个版本的虚函数,可能是基类中的版本也可能是派生类中的版本,判断的依据是引用(或指针)所绑 定的对象的真实类型。 * 与非虚函数在编译时绑定不同,虚函数是在运行时选择函数的版本,所以动态绑定也叫运行时绑定(run-time binding)。 * * 虚函数的指针会保存到class里的"虚函数表"中。每一个对象都会一个自己的“虚函数表”。类似对函数指针列表。 * * */ using namespace::std; class Animal { public: string name; string attr; Animal(string n):name(n){}; Animal(string n,string a):name(n),attr(a){}; void runing(int i) { cout<<"animal("<<name <<") can runing "<<i<<" meter!"<<endl; } void moving() { cout<<"animal ("<<name <<")can moving !"<<endl; } virtual void eating() //虚函数。 { cout<<"animal ("<<name <<")must eat something!"<<endl; } }; class DOG: public Animal { public: #if 1 using Animal::Animal; //**这个特性叫继承构造函数** 此句表示子类可以使用Animal类里的所有构造函数,不需要程序员再手动定义一遍了,在此例中省去了如下代码。 #else DOG(string t):Animal(t){}; DOG(string t,string x):Animal(t,x){}; #endif void runing(float f) { cout<<"dog run fast "<<f<<" meter!" <<endl; } void moving() { cout<<"dog move fast!"<<endl; } }; class Fish: public Animal { public: using Animal::Animal; void eating() { cout<<"fish eat in the water"<<endl; } }; /* * 由于moving不是虚函数,所以p->moving,使用了animal里的 moving * */ void test_moving(class Animal *p) { p->moving(); } /* * eating在基类中是一个虚函数,所以test_eating的入参是animal类型,但在程序运行过程中 “动态地”找到真正的数据类型,并调用真正的方法函数。 * 这也是多态的一种方式。 * * */ void test_eating(class Animal* p) { p->eating(); } void test_eating_moving(class Animal& p) { p.eating();//是虚函数,在运行时动态来决定。 p.moving(); //moving不是虚函数,在编译时,决定了它是animal的moving } int main(void) { class DOG dog("Dog bingo"); class Animal a("Common-Animal"); class Fish fish("Shark"); dog.moving(); a.moving(); cout<<"dog is test_moving"<<endl; test_moving(&dog); dog.runing(4.4); //这里在编译时dog.runing函数就已经是DOG类的runing函数了。 dog.runing(9);//int 9在这里就被强制转义成float 了。 cout<<"fish test eating"<<endl; test_eating(&fish); fish.runing(4);//由于 Fish类里无runing函数,它在静态编译时使用了父类Animal的runing函数。 cout<<"-test_eating_moving(dog)----"<<endl; test_eating_moving(dog); cout<<"-test_eating_moving(fish)----"<<endl; test_eating_moving(fish); cout <<"----------------sizeof(dog),sizeof(animal)and sizeof(fish)"<<endl; cout<<"dog size:"<<sizeof(dog)<<endl; cout<<"animal size:"<<sizeof(a)<<endl; cout<<"class Fish size:"<<sizeof(class Fish)<<endl; cout <<"size=8, this is a virtial_function_table ‘s size, this table has only function point. so is 8"<<endl; return 0; }

C++虚函数与非虚函数的区别。

标签:ati   pac   some   func   ios   names   动态   fast   turn   

原文地址:https://blog.51cto.com/yaxinsn/2423018

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!