码迷,mamicode.com
首页 > 其他好文 > 详细

继承中的虚函数、纯虚函数、普通函数

时间:2019-04-26 22:57:53      阅读:294      评论:0      收藏:0      [点我收藏+]

标签:detail   运行   比较   重写   public   成员函数   ref   include   函数实现   

一、虚函数

         被virtual关键字修饰的类成员函数就是虚函数。虚函数的作用就是实现运行时的多态性,将接口与实现分离。简单理解就是相同函数有着不同的实现,但因个体差异而采用不同的策略。

         基类中提供虚函数的实现,为派生类提供默认的函数实现。派生类可以重写基类的虚函数以实现派生类的特殊化。如下:

class Base{

public:

        virtual void foo() { cout<<"Base::foo() is called"<<endl; }

};

class Derived : public Base {

public:

        void foo() { cout<<"Derived::foo() is called"<<endl; }

};


int main(void)

{

       Base *b = new Derived();

       b->foo(); // b虽然是类型Base的指针 但是实际上指向的是Derived类 所以调用的函数foo是Derived类的

       return 0;

}


二、纯虚函数

        纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加"=0"。

        包含纯虚函数的类被称为“抽象类”,抽象类不能实例化成对象,但是可以定义抽象类的引用和指针。此外,实现了该纯虚函数的派生类可以实例化成对象。

class A
{
public:
        virtual void out1(string s)=0;
        virtual void out2(string s)
       {
           cout<<"A(out2):"<<s<<endl;
       }
};


三、普通函数

普通函数是静态编译的,没有运行时多态,只会根据指针或引用的“字面值”类对象,调用自己的普通函数。

普通函数是基类为派生类提供的“强制实现”。

因此,在继承关系中,派生类不应该重写基类的普通函数,因为函数的调用只与类对象的字面值有关。下面是搬来的一段代码:

#include <iostream>
using namespace std;

class A
{
public:
     virtual void out1()=0;  ///由子类实现
     virtual ~A(){};
     virtual void out2() ///默认实现
     {
         cout<<"A(out2)"<<endl;
     }
     void out3() ///强制实现
     {
         cout<<"A(out3)"<<endl;
     }
};

class B:public A
{
public:
     virtual ~B(){};
     void out1()
     {
         cout<<"B(out1)"<<endl;
     }
     void out2()
     {
         cout<<"B(out2)"<<endl;
     }
     void out3()
     {
         cout<<"B(out3)"<<endl;
     }
};

int main()
{
     A *ab=new B;
     ab->out1();
     ab->out2();
     ab->out3();
     cout<<"************************"<<endl;
     B *bb=new B;
     bb->out1();
     bb->out2();
     bb->out3();

    delete ab;
     delete bb;
     return 0;
}



执行结果:

B<out1>

B<out2>

A<out3>

*****************************************

B<out1>

B<out2>

B<out3>


四、虚函数与构造函数和析构函数

      1) 当存在类继承并且析构函数中有必须要进行的操作时(如需要释放某些资源,或执行特定的函数)析构函数需要是虚函数,否则若使用父类指针指向子类对象,在delete时只会调用父类的析构函数,而不能调用子类的析构函数,从而造成内存泄露或达不到预期结果;

    2) 构造函数不能为虚函数:构造函数在进行调用时还不存在父类和子类的概念,父类只会调用父类的构造函数,子类调用子类的,因此不存在动态绑定的概念;但是构造函数中可以调用虚函数,不过并没有动态果,只会调用本类中的对应函数;

       3) 静态成员函数不能为虚函数:静态成员函数是以类为单位的函数,与具体对象无关,虚函数是与对象动态绑定的。


这篇博客介绍的比较详细,我就不搬了……


参考文献:

     1> C++ 虚函数表解析

     2> C++ 在继承中虚函数、纯虚函数、普通函数,三者的区别

     3> C++里神奇的虚函数

     4> 虚函数实现机制、构造函数、析构函数能否为虚函数,与纯虚函数

继承中的虚函数、纯虚函数、普通函数

标签:detail   运行   比较   重写   public   成员函数   ref   include   函数实现   

原文地址:https://www.cnblogs.com/Lilu-1226/p/10776873.html

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