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

发布时间:2020-07-08 19:21:02 作者:yaxinsn
来源:网络 阅读:579
#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;
}
推荐阅读:
  1. C++中的 虚函数 纯虚函数 虚基类(virtual)
  2. 虚函数与普通函数的关系

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

动态绑定 继承构造函数

上一篇:KS02-05 pri 文件有啥用?

下一篇:HTML&CSS基础学习笔记14—有序列表及列表嵌套

相关阅读

您好,登录后才能下订单哦!

密码登录
登录注册
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》