虚函数和纯虚函数

来源:互联网 发布:淘宝运营方案模板 编辑:程序博客网 时间:2024/06/06 06:54

1、基本形式:
virtual ReturnType Function_1();            //虚函数声明
virtual ReturnType Function_2() = 0;      //纯虚函数声明
先讲示例吧,再总结结论。

2、示例:
class Animail{
public:
    void Function_1() {cout <<"Animail::Function_1()"<<endl;};
};

classDog: public Animail{
 public:
     void Function_1() {cout <<"Dog::Function_1()"<<endl;};
};
int main(int argc, char* argv[])
{
    Animail*p = NULL; //定义基类的指针
    Animail cAnimail;
    Dog cDog;

    p = &cAnimail;
    p->Function_1();

 

    p =&cDog;
    p->Function_1();
    return 0;
}

这段代码的输出结果是什么呢?起初我认为是:Animail::Function_1()与Dog::Function_1(),因为第一次输出是引用基类Animail的实例,第二次输出是引用子类Dog的实例。事实上答案是Animail::Function_1()与 Animail::Function_1(),为什么呢?

这里我们需要明白:你就记住,不管引用的实例是哪个类的,当你调用的时候,系统会调用左值那个对象所属类的方法。比如说上面的代码类Animail和 Dog都有一个Function_1函数,因为p是一个Animail类的指针,所以不管你将p指针指向类Animail或是类Dog,最终调用的函数都是类Animail的Function_1函数。这就是静态联篇,编译器在编译的时候就已经确定好了。可是如果我想实现跟据实例的不同来动态决定调用哪个函数呢?这就须要用到虚函数(也就是动态联篇)。

class Animail{
public:
    virtual void Function_1() {cout <<"Animail::Function_1()"<<endl;};
};

class Dog: public Animail{
 public:
     virtual void Function_1() {cout <<"Dog::Function_1()"<<endl;};
};

在基类的成员函数前加关键字virtual,则表示这个函数是一个虚函数。
所谓虚函数就是在编译的时候不确定要调用哪个函数,而是动态决定将要调用哪个函数。它的作用就是为了能让这个函数在它的子类里面可以被重载,这样的话,编译器就可以使用后期绑定来达到多态了,也就是:用基类的指针来调用子类的这个函数。
要实现虚函数必须保证派生类的函数名与基类相同,参数名参数类型等也要与基类相同。但派生类中的virtual关键字可以省略,也表示这是一个虚函数。
下面来分析一下代码,声明一个基类的指针(必须是基类,反之则不行)p,把p指向类Animail的实例cAnimail,调用Function_1函数,这时系统会判断p所指向的实例的类型,如果是Animail类的实例就调用Animail类的Function_1函数,如果是Dog类的实例cDog就调用Dog类的Function_1函数。

下面来讲一下纯虚函数,包含纯虚函数的类也可叫虚基类或者抽象类
class Animail{
public:
    virtual void GetColor()  = 0;
};

classDog : public Animail{
 public:
     virtual void GetColor() {cout <<"Yellow"endl;};
};

classPig : public Animail{
public:
 virtual void GetColor() {cout <<"White"<<endl;};
};

如上代码,定义了一个动物类(Animail),类中有一函数GetColor可取得动物颜色,但动物有很多很多种,颜色自然无法确定,所以就把它声明为纯虚函数,也就是光声明函数名不去定义(实现)它,类Dog继承了Animail并实现了里面的代码,返回黄色。Bike类同样道理。有一点须要注意一下,纯虚函数不能实例化,但可以声明指针,所以上面的main函数中: Animail cAnimail; 编译器会告诉你:由于它的成员的原因,无法instantiate 抽象类Animail,并且警告你GetColor() 没有定义。

虚函数
    1, 虚函数是非静态的、非内联的成员函数。
    2, 若类中一个成员函数被说明为虚函数,则该成员函数在派生类中可能有不同的实现。当使用该成员函数操作指针或引用所标识的对象时,对该成员函数调用可采用动态联编。
    5, 定义了虚函数后,程序中声明的指向基类的指针就可以指向其派生类。在执行过程中,该函数可以不断改变它所指向的对象,调用不同版本的成员函数,而且这些动作都是在运行时动态实现的。虚函数充分体现了面向对象程序设计的动态多态性。虚函数充分体现了面向对象程序设计的动态多态性。

纯虚函数
    1, 当在基类中不能为虚函数给出一个有意义的实现时,可以将其声明为纯虚函数,其实现留待派生类完成。
    2, 纯虚函数的作用是为派生类提供一个一致的接口,它只是个函数的声明而已,它告诉编译器,在这个类中的这个纯虚函数是没有函数定义的,该类不能创建对象(即不能实例化),但可以声明指针,该类的派生类负责给出这个虚函数的重载定义。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 淘宝退货运费太贵卖家不退怎么办 顺丰文件丢失怎么办 京豆负9千多怎么办 京东押话题没了怎么办 没退运费险怎么办 本人身份证丢了怎么办 输入农行卡三次怎么办 花呗支付超限怎么办 在商场买到破衣服怎么办 vans鞋子磨脚怎么办 衣服白领子发黄怎么办 白衬衣染上黑色怎么办 车超过年检日期怎么办 用过期卫生间痒怎么办 驾照过期一个礼拜怎么办 月经总是后漏怎么办 护垫掉厕所里怎么办 健身房老板拿钱跑了怎么办 手机游戏变竖屏了怎么办 轮胎钢圈处磨损怎么办 屋里有刺鼻气味怎么办 脸上都是荧光剂怎么办 mac系统卡死了怎么办 笔记本关机要很久怎么办 mac关不了机怎么办 mac蓝屏无法开机怎么办 凤凰系统内存小怎么办 proe安装完成打不开怎么办 绿叶竹根发黑怎么办 月经期间肚子凉怎么办 来月经肚子冷怎么办 月经越来越少了怎么办 卫生巾闷出红疹子痒怎么办 开动物检疫证明怎么办 打桩机钻头掉了怎么办 临牌怎么办没有合格证 没有合格证怎么办零牌 贴了一等品瓷砖怎么办 香港过关货物被退港怎么办 换检验标过期怎么办 电动车合格证丢了怎么办