目录
一 虚函数
当我们使用基类引用或者指针调用一个虚函数成员函数,会执行动态绑定。
1:对虚函数的调用可能在运行时才会被解析。
编译器产生的代码知道运行时才能确定调用的是哪个版本的函数。被调用的函数是与绑定到引用或指针的对象的动态类型匹配的那一个。必须要搞清楚一点:动态绑定只有当我们通过指针或者引用调用虚函数时才会发生。
1:多态性
我们把具有继承关系的多个类型称为多态类型。引用和指针的静态类型与动态类型不同这一事实是c++语言支持多态性性的根本所在。
派生类中的虚函数:派生类的函数如果覆盖了某个继承而来的虚函数,则它的形参必须和它父类的形参一致,返回类型也必须和基类函数一致。尽量在派生类的虚函数后加关键字“override”。
二 抽象基类
:这种抽象基类很适合做某个需要多种实现方式的接口类
例如:bulk_quote类,他可以直接继承quote,但是需要自带成员。通过Disc_quote继承就不需要自带成员。
例如:在纯虚函数 double net_price(size_t n) const=0;这就是纯虚函数。
含有(或者未经覆盖的直接继承)纯虚函数的类是抽象基类。他主要负责定义接口 ,而后续派生类可以覆盖其接口。抽象基类不可自定义对象。
class Disc_quote :public Quote{
public:
Disc_quote();
Disc_quote(const std::string &bookid,double price,size_t qty,double disc)
:quote(bookid,price),quantity(qty),discount(dis){}
double net_price(size_t n)const =0; //纯虚函数不允许自定义对象
private:
std::size_t quantity =0;//折扣数量最小值
double discount=0.0;// 折扣
};
class Bulk_quote :public Disc_quote{ //这相比直接定义为Quote类的派生类少了很多成员,更方便拓展
public:
Bulk_quote ();
Bulk_quote (const std::string &b,double p,size_t q,double disc)
:Disc_quote(b, p, q, disc){}
net_price(std::size_t n)const override;
};
三 访问控制与继承
受保护的成员对于派生类的成员和友元函数来说是可访问的。派生类的成员或者友元只能通过派生类对象来访问基类的受保护成员。
例如:class Base{
protected:
int prot_men;
};
class Sneaky :public Base{
friend void clobber(Sneaky &);//正确,能访问Sneaky::port_men
friend void clobber(Base&);//错误,不能访问Sneaky::port_men
};
1:派生类向基类转换的可访问性
1):只有当D公有的继承B,用户代码才能使用派生类向基类转换;如果D继承B的方式是受保护的或者私有的,则用户代码不能使用该转换。
2):不论D以什么方式继承B,D的成员函数和友元都能使用派生类向基类转换(基类的引用或者指针做左值,右值是派生类对象)。
3):如果D继承B的方式是公有的或者受保护的,则D的派生类成员和友元都可以使用D向B的类型转换。
四 继承中的类作用域
1:指针或者引用对象 可以往父类方向寻找对应的函数,不允许向派生类方向寻找。:
2:派生类的成员将隐藏同名的基类成员。我们可以通过域运算符来使用一个被隐藏的基类成员。
3:除了覆盖继承而来的虚函数外,派生类最好不要重用其他定义在基类中的名字。