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

Posted lilu-1226

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了继承中的虚函数纯虚函数普通函数相关的知识,希望对你有一定的参考价值。

一、虚函数

         被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> 虚函数实现机制、构造函数、析构函数能否为虚函数,与纯虚函数

以上是关于继承中的虚函数纯虚函数普通函数的主要内容,如果未能解决你的问题,请参考以下文章

9-2:C++多态之纯虚函数和抽象类以及接口继承和实现继承

虚函数纯虚函数虚函数与析构函数

Hello,C++纯虚函数和抽象类

c++ 虚函数和纯虚函数

C++ 纯虚函数

虚函数与纯虚函数