面向对象(primer)

成员函数与继承

  在c++中,基类必须将其函数分为两类:一种是希望派生类进行覆盖的函数,这类函数用virtual进行修饰并定义为虚函数,通过运行时的动态绑定来决定执行哪个版本的函数;另一类是基类需要派生类继承的函数,该类函数的解析发生在编译过程中。

  如果函数定义为纯虚函数的话(const  = 0),那么基类不允许实现该类函数,只能由派生类实现;对于普通的虚函数而言,基类可以实现一个缺省的版本,既派生类不覆盖该函数的话,采用从基类继承的默认实现。

protect 机制

  派生类可以继承定义在基类中的成员,但是派生类的成员函数不一定有权访问从基类继承而来的成员。和其他使用基类的代码一样,派生类能访问公有成员,而不能访问私有成员。不过在某些时候基类中还有这样一种成员,基类希望它的派生类有权访问该成员,同时禁止其他用户访问。我们用受保护的(protected))访问运算符说明这样的成员。

 

 

虚函数的默认实参和回避机制

  虚函数的默认实参的值由本次调用的静态类型决定。当一个派生类的虚函数需要调用期覆盖的基类虚函数版本时,可以通过作用域运算符来实现这一目的。

double undiscounted = basep->Quote::net_price(20) // Quote是basep对应的基类

抽象类

  含有(或者未经覆盖直接继承)纯虚函数的类是抽象类。抽象类负责定义接口,而后续的其他类可以覆盖该接口。因此不能直接创建一个抽象类的对象。 

2. 访问控制和继承

派生类控制符 

  派生类控制符对于其成员的访问权限没有什么影响,主要用于限制其用户以及派生类的派生类对基类成员的访问权限。(569处补充例子)

派生类向基类转换的可访问性

  派生类向基类的转换是否可访问由使用该转换的代码决定,同时派生类的派生访问说明符也会有影响。假定D继承自B:

  • 只有当D共有的继承B时,用户代码才能使用派生类向基类的转换;继承的方式是私有的,则用户代码不能使用该转换。
  • 派生类的向其直接基类的类型转换对于派生类的成员和友元而言永远是可访问的。
  • 如果D继承B的方式是公有或者受保护的,则D的派生类的成员可以使用D向B的转换;私有继承方式不行。

  struct中成员默认为public,class默认为private

改变个别成员的可访问性(571页)

 

通过作用域运算符来使用隐藏的成员

  可以通过作用域运算符来使用一个被隐藏的基类成员:

struct Derived : Base {
      int get_base_mem() {return Base::men};  
}

  作用域运算符将覆盖原有的查找规则,并指示编译器从Base类的作用域开始查找mem。如果派生类的成员与基类的某个成员同名,则派生类将在其作用域内隐藏该基类成员。即使派生类成员和基类成员的形参列表不一致,基类成员依旧会被隐藏。

3. 构造函数与拷贝控制

虚析构函数

  只要基类的析构函数是虚函数,就能确保我们delete基类指针时运行正确的析构函数版本。如果一个类定义了析构函数,编译器不会为这个类合成移动操作

合成拷贝控制与继承

  基类或者派生类合成拷贝控制成员的行为与其他合成的构造函数、赋值运算符或析构函数类似:他们对类本身的成员依次进行初始化、赋值或销毁的操作。其中,派生类的合成函数还掉用基类的合成函数来完成对基类成员的操作

移动操作与继承

  基类缺少移动操作会阻止派生类拥有自己的合成移动操作,当确定派生类需要移动操作的时候,应该首先在基类中修改。

(582)

posted @ 2021-07-11 21:43  猪突猛进!!!  阅读(544)  评论(0编辑  收藏  举报