C++Primer第5版读书笔记(第15章)

来源:互联网 发布:java 发布webservice 编辑:程序博客网 时间:2024/05/18 00:49

第15章 面向对象程序设计
15.2 定义基类和派生类
15.2.1 定义基类

  1. 基类通常应该定义一个虚析够函数。
  2. 任何构造函数之外的非静态函数都可以是虚函数。
  3. 关键字virtual只能出现在类内部的声明语句之前而不能用于类外部的函数定义。
  4. 派生类可以访问基类的公有成员,而不能访问私有成员。protected访问权限派生类可以访问但其他对象不能访问。

15.2.2 定义派生类

  1. 派生类通过使用类派生列表指明继承的基类,类派生列表的形式为:首先一个冒号,后面紧跟以逗号分隔的基类列表,其中每个基类前面可以有以下三种访问说明符中的一个:public、protected或者private。
  2. 派生类对象及派生类向基类的类型转换。
  3. 如果想将某个类用作基类,则该类必须已经定义而非仅仅声明。
  4. 防止继承的发生,在定义类时,可以在类名后加一个关键字final防止其他类继承。

15.2.3 类型转换与继承

  1. 基类的指针或引用可绑定到派生类对象上,同时智能指针类也支持派生类向基类的类型转换。
  2. 派生类向基类的自动类型转换只对指针或引用类型有效。
  3. 当用一个派生类对象为一个基类对象初始化或赋值时,只有该派生类对象中的基类部分会被拷贝、移动或赋值,它的派生类部分将被忽略掉。

15.3 虚函数

  1. 基类中的虚函数在派生类中隐含地也是一个虚函数。当派生类覆盖了某个虚函数时,该函数在基类中的形参必须与派生类中的形参严格匹配。
  2. 派生类中虚函数的返回类型也必须与基类函数匹配,但一个例外是,当类的虚函数返回类型是类本身的指针或引用时,上述规则无效。
  3. 可以使用关键字override来说明派生类中的函数是覆盖基类中的虚函数,关键字放在函数参数列表后面。
  4. 可以使用关键字final来防止该函数在派生类中被覆盖,关键字放在函数参数列表后面。
  5. 虚函数也可以拥有默认实参。如果某次函数调用使用了默认实参,则该实参值由本次调用的静态类型决定(即如果通过基类的引用或指针调用函数,则使用基类中定义的默认实参,即使实际运行的是派生类中的函数版本也是如此)。
  6. 可以通过使用作用域运算符来强制执行虚函数的某个特定版本。

15.4 抽象基类

  1. 纯虚函数:无须定义,在函数体的位置(声明语句的分号之前)书写=0就可以将一个虚函数说明为纯虚函数。可以为纯虚函数提供定义,不过函数体必须定义在类的外部。
  2. 含有(或者未经覆盖直接继承)纯虚函数的类是抽象基类。不能(直接)创建一个抽象基类的对象。

15.5 访问控制与继承
受保护的成员(protected)

  • 和私有成员类似,受保护的成员对于类的用户来说是不可访问的。
  • 和公有成员类似,受保护的成员对于派生类的成员和友元来说是可访问的
  • 派生类的成员或友元只能通过派生类对象来访问基类的受保护成员。派生类对于一个基类对象中的受保护成员没有任何访问特权。即对于普通的基类对象中的成员不具有特殊的访问权限。
  • 派生访问说明符对于派生类的成员(及友元)能否访问其直接基类的成员没有什么影响,对基类成员的访问权限只与基类中的访问说明符有关。派生访问说明符的目的是控制派生类用户(包括派生类的派生类在内)对于基类成员的访问权限。

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

  • 只有当D公有地继承B时,用户代码才能使用派生类向基类的转换;如果D继承B的方式是受保护的或者私有的,则用户代码不能使用该转换。
  • 不论D以什么方式继承B,D的成员函数和友元都能使用派生类向基类的转换,派生类向其直接基类的类型转换对于派生类的成员和友元来说永远是可访问的。
  • 如果D继承B的方式是公有的或者受保护的,则D的派生类的成员和友元可以使用D向B的类型转换,反之,如果D继承B的方式是私有的,则不能使用。

友元与继承

  1. 友元关系既不能传递,也不能继承。

改变个别成员的可访问性

  1. 使用using声明可以改变派生类继承的某个名字的访问级别。
class Base{public:    std::size_t size() const {return n;}protected:    std::size_t n;};class Derived:private Base{punlic:    using Base::size;protected:    using Base::n;};

默认的继承保护级别

  1. 默认派生运算符由定义派生类所用的关键字来决定,默认情况下,使用class关键字定义的派生类是私有继承的,而使用struct关键字定义的派生类是公有继承的。

15.7 构造函数与拷贝控制
15.7.1 虚析构函数

  1. 虚析构函数将阻止合成移动操作,如果一个类定义了析构函数,即使它通过=default的形式使用了合成的版本,编译器也不会为这个类合成移动操作。

15.7.4 继承的构造函数

  1. 派生类继承基类构造函数的方式是提供一条注明了基类名的using声明语句,对于基类的每个构造函数,编译器都在派生类中生成一个形参列表完全相同的构造函数。using声明不会改变该构造函数的访问级别,using声明语句不能指定explicit或constexpr,如果基类的构造函数是explicit或constexpr,则继承的构造函数也拥有相同的属性。
//编译器生成的构造函数形如:derived(params) : base(args){}
0 0