《C++Primer》第十五章:面向对象程序设计

  1. 面向对象程序设计的核心思想是数据抽象、继承和动态绑定。使用数据抽象,我们将类的接口和实现分离;使用继承,可以对相似的关系进行建模;使用动态绑定,可以在一定程度上忽略相似类的区别,并以统一的方式使用它们的对象,即在运行时选择执行函数的版本。
  2. 先简单的记住一个原则,作为继承关系中的根节点的基类通常都会定义一个虚析构函数,即使该函数不执行任何代码。
  3. 需要动态绑定的函数被写成虚函数,虚函数不是一定要被重写的。任何构造函数之外的非静态函数都可以是虚函数。成员函数如果没有被声明为虚函数,则其解析过程发生在编译时而非运行时。在派生类中覆盖虚函数时,可以再次使用virtual关键字,但这不是必须的,因为一旦某个函数被声明为虚函数,则在所有派生类中他都是虚函数。
  4. 派生类可以访问公有成员而不能访问私有成员,可以使用保护成员给派生类开放访问权限。
  5. 如果基类定义了一个静态成员,则在整个继承体系中只存在该成员的唯一定义,对于每个静态成员来说,都只存在唯一的实例。
  1. 用于基类的类必须已经定义,不能仅仅是被声明。
  2. 在定义时,类名后加一个关键字final,表示该类不允许被继承。
  3. 通常来说一个类的类型在编译的时候可以确定,这也是静态语言的优势之一。但是当使用存在继承关系的类型时必须区分其静态类型动态类型。表达式的静态类型在编译时是确定的,而动态类型是变量的内存中对象的实际类型,运行时才可以确定。只有引用或者指针也可能出现动态类型与静态类型不一致的情况,因为基类的引用或者指针可以绑定到派生类对象上。动态类型决定了虚函数在运行时执行哪个版本,也是多态性产生的原因。而一个普通对象动态类型与静态类型一致,所以执行虚函数无需运行时确定,也就不存在多态性。
  4. 一个对象、运用或指针的静态类型决定了该对象的哪些成员是可见的,因此如果在派生类中定义了一个函数(不是重写的基类虚函数),那么基类的指针是不能调用该函数的,只要虚函数才能这么做,注意到虚函数定义在基类的作用域中,所以是可以被找到并调用的。
  5. 在派生类中对于重写的虚函数加上override标记有助于更清晰的表达程序员的意图,也有助于帮助编译器发现代码中可能存在的问题。override使得被标记的函数一定要能在基类中找到对应的虚函数,否则就报错。
  6. 可以使用作用域符来关闭虚函数的动态绑定机制,强制执行某一个版本的虚函数,这一过程在编译时确定。
  7. 在函数体的位置加上=0,可以将一个虚函数说明为纯虚函数。这种方式只能出现在类内部。含有纯虚函数的类是抽象基类。
  8. 派生访问说明符不影响派生类自身对于基类的访问,影响的是实例化的派生类对象对于基类成员的访问。以public方式继承基类,派生类对象可以访问基类的成员;以private方式继承基类,基类的成员在派生类中变成private,不可以通过派生类对象访问基类成员。
  9. 友元关系不能传递,友元关系也不能继承。
  10. 派生类的作用域嵌套在基类的作用域中,如果一个名字在派生类的作用域内无法正确解析,编译器将在外层的基类中继续寻找该名字的定义。
  11. 如果不是虚函数,而派生类中定义了基类中的同名函数(即使形参列表不一致),由于嵌套作用域的存在,内层(派生类)中的函数名会隐藏内层(基类)的函数名。类似于普通的作用域与变量,可以使用作用域运算符指定使用哪个名字。
本站总访问量