虚函数和纯虚函数的区别

来源:互联网 发布:js1-400拌和机技术数据 编辑:程序博客网 时间:2024/06/06 16:27

1、定义一个函数为虚函数,不代表函数为不被实现的函数
    定义他为虚函数是为了允许用基类的指针来调用子类的这个函数

class  A  { public:  virtual void foo() { cout<<"A::foo() is called"<<endl;  } };  class B : public A  { public:  void foo()  { cout<<"B::foo() is called"<<endl; } };  int main(void)  { A *a = new B();  a->foo(); // 在这里,a虽然是指向A的指针,但是被调用的函数(foo)却是B的! 基类的指针调用子类的foo函数 return 0;  }

2、定义一个函数为纯虚函数,才代表函数没有被实现
    定义他是为了实现一个接口,起到一个规范的作用,规范继承这个
    类的程序员必须实现这个函数。

虚函数主要实现多态机制避免二义性问题  
虚函数与纯虚函数最大的区别:含有纯虚函数的类(抽象类)不能定义对象。  

比如:

class CA                                           class CB    
{                                                {
public:                                             public:
    virtual void fun() 0;  // 说明fun函数为纯虚函数            virtual void fun();
    virtual void fun1();      // 说明fun1函数为虚函数             virtual void fun1();
};                                                };

void main()
{
    CA a;   // 不允许,因为类CA中有纯虚函数
    CB b;   // 允许,因为类CB中没有纯虚函数
}

2、虚函数

class A的成员函数print()是虚函数,那么class B:public A中的print()也自然变成了虚函数。

当基类中的某一成员函数声明为虚函数后,派生类中的同名函数(函数名相同、参数列表完全一致、返回值类型相关)自动成为虚函数。

(1)非类的成员函数不能定义为虚函数,类的成员函数中静态成员函数和构造函数也不能定义为虚函数,但可以将析构函数定义为虚函数。

(2)只需要在声明函数的类体中使用关键字“virtual”将函数声明为虚函数,而定义函数时不需要使用关键字“virtual”。

(3)如果声明了某个成员函数为虚函数,则在该类中不能出现和这个成员函数同名并且返回值、参数个数、类型都相同的非虚函数。在以该类为基类派生类中,也不能出现这种同名函数。


3、C++纯虚函数
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义自己的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”
virtual void funtion1()=0

纯虚函数就是没有函数体的,必须在派生类中重载函数虚函数可以有函数体,如果派生类中没有重载函数,则调用父类的函数

虚函数必须实现,如果不实现,编译器将报错。

classa { 

virtualb()=0;//纯虚函数

 virtualc(){...}//虚函数 

};  


4、抽象类

抽象类是一种特殊的类,它是为了抽象和设计的目的为建立的,它处于继承层次结构的较上层。
(1)抽象类的定义:  称带有纯虚函数的类为抽象类。
(2)抽象类的作用:
抽象类的主要作用是将有关的操作作为结果接口组织在一个继承层次结构中,由它来为派生类提供一个公共的根,派生类将具体实现在其基类中作为接口的操作。所以派生类实际上刻画了一组子类的操作接口的通用语义,这些语义也传给子类,子类可以具体实现这些语义,也可以再将这些语义传给自己的子类。

(3)抽象类是不能定义对象的。

总结:

1、纯虚函数声明如下: virtual void funtion1()=0; 纯虚函数一定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但可以声明指向实现该抽象类的具体类的指针或引用。
2、虚函数声明如下:virtual ReturnType FunctionName(Parameter);虚函数必须实现,如果不实现,编译器将报错,错误提示为:
error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"
3、对于虚函数来说,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。
4、实现了纯虚函数的子类,该纯虚函数在子类中就变成了虚函数,子类的子类即孙子类可以覆盖该虚函数,由多态方式调用的时候动态绑定。
5、虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是通过基类访问派生类定义的函数。
6、在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。
7、友元不是成员函数,只有成员函数才可以是虚拟的,因此友元不能是虚拟函数。但可以通过让友元函数调用虚拟成员函数来解决友元的虚拟问题。
8、析构函数应当是虚函数,将调用相应对象类型的析构函数,因此,如果指针指向的是子类对象,将调用子类的析构函数,然后自动调用基类的析构函数。

有纯虚函数的类是抽象类,不能生成对象,只能派生。他派生的类的纯虚函数没有被改写,那么,它的派生类还是个抽象类。
定义纯虚函数就是为了让基类不可实例化化
因为实例化这样的抽象数据结构本身并没有意义。
或者给出实现也没有意义
实际上我个人认为纯虚函数的引入,是出于两个目的
1、为了安全,因为避免任何需要明确但是因为不小心而导致的未知的结果,提醒子类去做应做的实现。
2、为了效率,不是程序执行的效率,而是为了编码的效率。



原创粉丝点击