重载、重写、重用
作用域:重载函数,它们的作用域相同;而重写和重用的函数作用域不同,出现在继承关系中。
重载:函数名必须相同,但是函数参数列表必须不同,返回值无所谓。
重写:函数名,参数列表和返回值类型都必须相同。出现于虚函数中,也叫覆盖。
重用:函数名相同即可,出现于派生类重用定义了其基类中的函数名字,也叫隐藏。可以通过作用域来调用被隐藏的函数。重用体现了C++中一条规则--名字查找先于类型检查。
基类作用域与派生类作用域
派生类作用域嵌套于基类作用域之内,所以派生类才可以像使用自己的成员一样使用基类成员(在派生类有访问权限的情况下)。
虚函数
重写机制与动态绑定--调用哪个虚函数由所调用者的类型(派生类还是基类)决定,即无法再编译时判断函数的函数体,智能在运行时判断。
虚函数不能被修饰为静态。
虚函数表的实现:
虚函数表由vtbl(virtual table)和vptr(virtual table pointer)组成。
vtbl通常为一个函数指针数组或者链表。
vtbl中虚函数按照声明顺序存储,如果派生类重写了其基类的虚函数,则在其vtbl中代替其父类的位置。
在多继承中,每个有虚函数的基类都有自己的vtbl,派生类的虚函数成员(非继承或重写)被放在第一个基类的vbtl之中。
在多继承中,派生类需要额外的4N字节的空间来存储虚函数表的指针,其中N为其所有基类中包含虚函数的个数。
虚继承
1. 虚基类的构造由最底层的派生类负责,在构造顺序当中,虚基类排第一,与其在继承体系中的位置无关。
2. 当出现多个虚基类时,这些虚基类的构造顺序与其位置有关。该位置与多重继承中的子树有关,其所属子树顺序高者则先构造。
多重继承
1. 名字查找在派生类的所有直接基类中同时进行,以每个直接基类为树根形成的子树;如果该查找在超过一个子树(以直接基类为根的子树)中找到,则出现二义性。
2. 二义性是合法的,如果没有调用具有二义性的成员函数,则不会出错。在派生类中定义一个新版本的该成员函数可以解决二义性问题。
名字查找
1. 范围查找(名字)类 > 基类 > 命名空间
2. 重载决议(形参)
3. 可访问性检测(访问)
影响类的大小的三个因素
1. 语言特性早餐的影响,如vtbl。
2. 编译器在特殊情况下的优化处理,如对于空类,编译器会为其对象分配一个字节来区别各个对象的地址。
3. 边界调整,通过对齐从而优化总线的传输效率。
阻止拷贝构造和赋值构造