转自:程序员
https://blog.csdn.net/hackbuteer1/article/details/7558868面试
注:数据结构
该博主是个大牛,虽然早已经不更新了,可是分享了不少数据结构的面试题,值得翻阅学习。函数
重点笔记摘要以下:学习
下面是虚函数的一个典型应用。虚就虚在所谓“推迟联编”或者“动态联编”上,一个类函数的调用并非在编译时刻被肯定的,而是在运行时刻被肯定的。因为编写代码的时候并不能肯定被调用的是基类的函数仍是哪一个派生类的函数,因此被成为“虚”函数。请看例子:this
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的! return 0; }
虚函数只能借助于指针或者引用来达到多态的效果。spa
关于纯虚函数:.net
定义:设计
纯虚函数是在基类中声明的虚函数,它在基类中没有定义,但要求任何派生类都要定义本身的实现方法。在基类中实现纯虚函数的方法是在函数原型后加“=0”。如: virtual void funtion1()=0指针
为何要有纯虚函数?
由于有两个问题:
一、为了方便使用C++的多态特性,咱们经常须要在基类中定义虚函数。
二、在不少状况下,基类自己生成对象是不合情理的。例如,动物做为一个基类能够派生出老虎、孔雀等子类,但动物自己生成对象明显不合常理。
为了解决上述问题,引入了纯虚函数的概念。将函数定义为纯虚函数(方法:virtual ReturnType Function()= 0;),则编译器要求在派生类中必须予以重写以实现多态性。同时含有纯虚拟函数的类称为抽象类,它不能生成对象。这样就很好地解决了上述两个问题。(说的很是不错)
再次“啰嗦”1:声明了纯虚函数的类是一个抽象类。因此,用户不能建立类的实例,只能建立它的派生类的实例。派生类仅仅只是继承函数的接口。
再次“啰嗦”2:纯虚函数的意义,让全部的类对象(派生类对象)均可以执行纯虚函数的动做,但类没法为纯虚函数提供一个合理的缺省实现(无默认实现)。因此基类纯虚函数的声明就是在告诉子类的设计者,“你必须提供一个纯虚函数的实现,但我不知道你会怎样实现它”。
再次“啰嗦”3:避免了像“动物”这样的基类能够实例化,即不能生成对象。
总结:纯虚函数用来规范派生类的行为,即接口
理解了纯虚函数,没想到还能稍带把抽象类也学习了!
抽象类:
定义:称带有纯虚函数的类为抽象类
注意:
1. 抽象类只能做为基类来使用,其纯虚函数的实现由派生类给出。若是派生类中没有从新定义纯虚函数,而只是继承基类的纯虚函数,则这个派生类仍然仍是一个抽象类。若是派生类中给出了基类纯虚函数的实现,则该派生类就再也不是抽象类了,它是一个能够创建对象的具体的类。
2. 抽象类是不能定义对象的。
高级总结(仍是有不少不懂的地方):
总结:一、纯虚函数声明以下: virtual void funtion1()=0; 纯虚函数必定没有定义,纯虚函数用来规范派生类的行为,即接口。包含纯虚函数的类是抽象类,抽象类不能定义实例,但能够声明指向实现该抽象类的具体类的指针或引用。二、虚函数声明以下:virtual ReturnType FunctionName(Parameter);虚函数必须实现,若是不实现,编译器将报错,错误提示为:error LNK****: unresolved external symbol "public: virtual void __thiscall ClassName::virtualFunctionName(void)"三、对于虚函数来讲,父类和子类都有各自的版本。由多态方式调用的时候动态绑定。四、实现了纯虚函数的子类,该纯虚函数在子类中就变成了虚函数,子类的子类即孙子类能够覆盖该虚函数,由多态方式调用的时候动态绑定。五、虚函数是C++中用于实现多态(polymorphism)的机制。核心理念就是经过基类访问派生类定义的函数。六、在有动态分配堆上内存的时候,析构函数必须是虚函数,但没有必要是纯虚的。七、友元不是成员函数,只有成员函数才能够是虚拟的,所以友元不能是虚拟函数。但能够经过让友元函数调用虚拟成员函数来解决友元的虚拟问题。八、析构函数应当是虚函数,将调用相应对象类型的析构函数,所以,若是指针指向的是子类对象,将调用子类的析构函数,而后自动调用基类的析构函数。