动态绑定
在C++中,通过基类的引用/指针调用虚函数时,发生动态绑定。
基类的引用或指针既可以指向基类的对象也可以指向派生类的对象,这一事实是动态绑定的关键。
用引用或指针调用的虚函数在运行时确定,被调用的函数是引用或指针当前所指对象的实际类型所定义的。
访问控制
public和private标号
用户代码可以访问类的public成员而不能访问private成员,private成员只能由基类的成员和友元访问。
protected。
protected成员可以被派生类对象访问但不能被该类型的普通用户访问。
定义派生类。
为了定义派生类,使用“类派生列表”指定基类。如下形式
class classname: access-label base-class
派生类和虚函数
派生类一般会重定义所继承的虚函数,如果没有重定义某个虚函数,则使用基类中定义的版本。
派生类中的虚函数的声明必须与基类中的定义方式完全匹配。但有一个例外:
如果基类中的虚函数是返回对基类的引用 或指针,则派生类中的重定义版本,可以返回基类引用或指针,或派生类引用或指针。
什么时候使用动态绑定?
C++中的函数调用默认不使用动态绑定。要触发动态绑定,需要满足两个条件:
第一,只有指定为虚函数的成员函数才能进行动态绑定。在类中的声明使用关键字 virtual,
第二,必须通过 基类的引用或指针进行函数调用。
从派生类到基类的转换。
因为每个派生类对象都包含基类部分,所以可以将基类的引用绑定到派生类对象的基类部分,也可以用指向基类的指针指向派生 类的对象。
示例:
// function with an Item_base reference parameter
(const Item_base&, size_t);
基类引用
Item_base item; // object of base type
// ok: use pointer or reference to Item_base to refer to an Item_base object
passes reference to an Item_base object
p points to an Item_base object
基类引用绑定到派生类对象的基类部分。
Bulk_item bulk; // object of derived type
// ok: can bind a pointer or reference to Item_base to a Bulk_item object
print_total(bulk, 10); // passes reference to the Item_base part of bulk
p = &bulk; // p points to the Item_base part of bulk
覆盖虚函数机制
如果希望覆盖虚函数的动态绑定机制,并强制函数调用使用虚函数 的特定版本,这时可以使用作用域操作符。
Item_base *baseP = &derived;
// calls version from the base class regardless of the dynamic type of baseP
double d = baseP->Item_base::net_price(42);