C++学习笔记之虚构函数
虚函数(virtual修饰)
当成员函数是虚拟的时候,通过一个类对象(指针或引用 )而被调用的该成员函数 ,是在该类对象的动态类型中被定义的成员函数
虚拟函数机制只在使用指针和引用时才会如预期般地起作用
只有在通过基类指针或引用间接指向派生类子类型时,多态性才会起作用
纯虚函数
纯虚函数只是提供了一个可被子类改写的接口,它本身并不能通过虚拟机制被调用。
纯虚函数声明:虚函数声明后面紧跟赋值 0。
包含(或继承)一个或多个纯虚拟函数的类被编译器识别为抽象基类。试图创建一个抽象基类的独立类对象会导致编译时刻错误。
虚函数的静态调用:
方法:当用类域操作符调用虚拟函数时,我们改变了虚拟机制,使得虚拟函数在编译时刻被静态解析
原因:1. 提高效率(如果知道自己希望调用的实例,就不需要通过虚拟机制;如果虚函数是内联函数,在编译时就可以展开)
2. 纯虚函数不可以通过虚拟机制被调用 ,但也可以被静态调用 (声明纯虚函数并定义该函数)
实例:
Query *pquery = new NameQuery( "dumbo" );
// 通过虚拟机制动态调用 isA()
// 调用 NameQuery::isA() 实例
pquery->isA();
// 在编译时刻静态调用 isA
// 调用 Query::isA 实例
pquery->Query::isA();
虚函数和缺省实参
通过基类指针或引用调用派生类实例,则传递给它的缺省实参是由基类指定的。
原因:缺省实参不是在运行时刻决定的,而是在编译时刻根据被调用函数的对象的类型决定的。虚拟机制不直接支持这种行为:实际缺省实参是根据被调用函数的实际实例而决定的。
虚拟析构函数
在继承机制下的析构函数的行为如下:派生类的析构函数先被调用
作为一般规则,我们建议将类层次结构的根基类(声明了一个或多个虚拟函数)的析构函数声明为虚拟的。但是,不像基类的构造函数。一般地,基类的析构函数不应该是 protected
虚拟new操作符
new 操作符不能被声明为虚拟的,因为它是一个静态成员函数在构造类对象之前被应用到未使用的内存上
基类的构造函数中调用了一个虚拟函数,而基类和派生类都定义了该函数的实例将会怎么样?应该调用哪一个函数实例?
在基类构造函数中调用的虚拟实例总是在基类中活动的虚拟实例.实际上,在基类构造函数中,派生类对象只不过是一个基类类型的对象而已.
书籍:C++primer中文完美版(第三版).pdf