zoukankan      html  css  js  c++  java
  • C++虚函数

    C++中有一种名字让人觉得十分怪异的函数---虚函数。这样的称谓无论在JAVA抑或是PYTHON里面都没有,那么C++中的虚函数究竟是干什么用的,我们又应该在什么样的情景下使用它呢?

    虚函数通过关键字virtual 标识,也就是说,所有标识为virtual的函数均为虚函数。下面是一个例子:

    1 class Base{
    2 public:
    3     Base()=default;
    4     ~Base(){ std::cout<<"this object has been destoried!"<<std::endl;};
    5     
    6     virtual void printInfo(){
    7         std::cout<<"for demo porpuse only"<<std::endl;          
    8     }
    9 }

    在上面的例子中,在printInfo()函数前边加了关键字virtual,代表这个函数是虚函数,那么这个虚函数有什么用呢?换句话说,什么时候应该用它,而什么时候不应该用它呢?

    实际上,上面的打印函数加不加virtual都可以实现打印功能,为了回答上面提出的什么时候应当输赢的问题,接着看一段代码:

     1 class Collection{
     2 private: 
     3             int size;
     4 public:
     5             virtual const int size()const{
     6                   return size;
     7             }    
     8 }
     9 
    10 class vec: public Collection{
    11 public:
    12      const int size()const
    13     {
    14           //TODO: implement own size func.
    15     }
    16 }

    在上面的代码中,示例姓地写了一个基类Collection然后写了一个vec类继承基类,在基类中将获取元素个数的函数修饰为virtual,目的在于子类可以重写此方法,实现子类中特有的一些定义,之所以这么做,主要目的是为了符合多数人编程习惯。因此在基类中,如果想要子类继承时允许重写一些方法,那么可以将这些方法用virtual修饰。

    虚函数的作用不止是这样。我们知道在java里面有接口这一关键字interface, 但是C++中并没有这个关键字,那么怎么实现类似JAVA的接口功能呢?这时候纯虚函数就排上用场了,请看示例:

    1 class Base{
    2 public:
    3     virtual int size()=0;
    4 
    5 }

    在这一示例中,任何想要继承这一基类的子类,都必须重写size方法,这就跟JAVA里的接口功能非常一致了。

    讲到这里似乎虚函数主要的功能说完了,但是别急,虚函数还有另一个用途!!

    无论是C++也好JAVA也好,多态是一种均支持的技术,那么在使用多态的时候,C++中有什么要注意的地方呢?请看一个实例:

     1  class Base{
     2  public:
     3      ~Base(){
     4            std::cout<<"this is parent class object being printed!
    ";
     5      }
     6     void printInfo(){
     7       std::cout<<"base class.
    ";
     8     }
     9  }
    10  class Child:public Base{
    11  public:
    12       ~Child(){
    13           std::cout<<"this is child class object being printed!
    ";
    14      }
    15     void printInfo(){
    16       std::cout<<"child class.
    "
    17     }
    18 }
    19  void printClass(Base* b){
    20     b->printInfo();
    21      std::cout<<"calling printClass func.
    ";
    22  }

    当使用多态的时候,调用printClass方法可以执行,然而在子类与父类对象析构的时候,会发现只有父类的对象被析构,而子类对象的析构函数没有被调用。因此在此处,应当使用系函数修饰父类的析构函数。

    实际上当我们写一个类,不确定是否会被继承时,均应当将该类的析构函数标识为virtual,以免出现内存泄漏。

  • 相关阅读:
    WPF Video Tutorials
    英语词汇看病
    回车键的含义
    勘误《新概念》IV
    2010年春季C语言程序设计答疑时间地点安排
    勘误《新概念》III
    A potentially dangerous Request.Form value was detected from the client
    推荐WPF的好书(图书)
    *英语词汇交通
    英语词汇房地产
  • 原文地址:https://www.cnblogs.com/thugf/p/12907065.html
Copyright © 2011-2022 走看看