虚函数相关的知识

先上一段代码,简单易懂:

#include <iostream>

class Graph{
protected:
    double x,y;
public:
    Graph(double x,double y){this->x=x;this->y=y;}
    ~Graph(){std::cout<<"~Graph "<<std::endl;}//-----------------2
    void showArea(){ std::cout<<"GraphArea "<< std::endl;}//-----3
};

class Rectangle:public Graph{
public:
    Rectangle(double x,double y):Graph(x,y){}
    ~Rectangle(){std::cout<<"~Rectangle "<<std::endl;}
    void showArea(){std::cout<<"RectangleArea "<< x*y << std::endl;}
};

int main(){
    Graph *graph;
    Rectangle rectangle(10,5);
    graph=&rectangle;
    graph->showArea();
    delete graph;
    return 0;
}

看一下程序的输出:

GraphArea 
~Graph 

和我们的预期不太一样,我们想要的肯定是执行Rectangle的showArea而不是父类的函数。想要实现该功能,需要把语句(3)变成virtual的虚函数。之后,结果:

RectangleArea 50
~Graph 
现在函数调用正常了,不过函数的析构函数还是不正常,同理,懂了吧,再加一个virtual,在语句(2)上。之后,结果:

RectangleArea 50
~Rectangle 
~Graph 
目前总结一下,正如我们看到的,父类类型的指针指向子类以后,如果父类的函数不是虚函数,则通过指针来执行该函数还是执行父类的函数。如果是虚函数,则执行子类的重载函数。鉴于这一点容易骗倒自己,所以最好将虚函数设计成纯虚函数,即修改语句(3)为:

virtual void showArea() = 0;

这样就有点像接口了,只写一个原型,让子类实现,并且不会出现错误。

总结虚函数:

  1.  C++默认是私有继承,而要使用多态,必须使用公有继承。
  2. 虚函数无论被继承n次,还是虚函数。
  3. 虚函数必须是成员函数,不能是构造函数(可以是析构函数),不能是友元函数,不能是static函数,不能是内联函数。
  4. 为了满足virtual的性质,C++需要为每个拥有virtual的class分配额外的空间(一个虚函数表指针,该指针指向一个虚函数表,来决定调用那个函数)。所以如果某个calss不是为了作为基类使用,或者不失为了具备多态性,不要添加virtual。
  5. 不要在构造函数和析构函数内调用virtual函数(构造和析构期间,这类调用不会下降到子类),这会造成不确定事件。






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值