zoukankan      html  css  js  c++  java
  • <C++Primer>第四版 阅读笔记 第四部分 “面向对象编程与泛型编程”

    继承和动态绑定与数据抽象一起成为面向对象编程的基础。

    模板使我们能够编写独立于具体类型的泛型类和泛型函数。


    第15章 面向对象编程

    面向对象编程基于三个基本概念:数据抽象、继承和动态绑定。在C++中,用类进行数据抽象,用派生类从一个类继承另一个类:派生类继承基类的成员。动态绑定使编译器能够在运行时决定是使用基类中定义的函数还是派生类中定义的函数。

    继承和动态绑定在两个方面简化了我们的程序:能够容易地定义与其他类相似但又不相同的新类,能够更容易地编写忽略这些相似类型之间区别的程序。


    面向对象编程的关键思想是多态性
    在C++中,多态性仅用于通过继承而相关联的类型的引用或指针。

    派生类能够继承基类定义的成员,派生类可以无须改变而使用那些与派生类型具体特性不相关的操作,派生类可以重定义那些与派生类型相关的成员函数,将函数特化,考虑派生类型的特性。

    在C++中,基类必须指出希望派生类重定义哪些函数,定义为virtual的函数是基类期待派生类重新定义的,基类希望派生类继承的函数不能定义为虚函数。

    通过动态绑定我们能够编写程序使用继承层次中任意类型的对象,无须关心对象的具体类型。使用这些类的程序无须区分函数是在基类还是在派生类中定义的。
    在C++中,通过基类的引用(或指针)调用虚函数时,发生动态绑定。引用(或指针)既可以指向基类对象也可以指向派生类对象,这一事实是动态绑定的关键。

    保留字 virtual 的目的是启动动态绑定。保留字 virtual 只在类内部的成员函数声明中出现,不能用在类定义体外部出现的函数定义上。

    派生类可以访问基类的 public 成员而不能访问 private 成员。protected 成员可以被派生类对象访问但不能被该类型的普通用户访问。(注意:这里都是访问2字,不是继承

    派生类只能通过派生类对象访问其基类的 protected 成员,派生类对其基类类型对象的 protected 成员没有特殊访问权限。

    派生类型必须对想要重定义的每个继承成员进行声明。

    1、派生类对象包含基类对象作为子对象。
    2、派生类中的函数可以使用基类的成员。
    3、用作基类的类必须是已定义的。
    4、基类本身可以是一个派生类。
    5、如果需要声明(但并不实现)一个派生类,则声明包含类名但不包含派生列表。

    要触发动态绑定,必须满足两个条件:第一,只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定;第二,必须通过基类类型的引用或指针进行函数调用

    基类类型的引用或指针可以引用基类类型对象,也可以引用派生类型对象。
    任何可以在基类对象上执行的操作也可以通过派生类对象使用。

    友元关系不能继承。基类的友元对派生类的成员没有特殊访问权限。

    如果基类定义了 static 成员,则整个继承层次中只有一个这样的成员。无论从基类派生出多少个派生类,每个 static 成员只有一个实例

    构造函数和复制控制成员不能继承,每个类定义自己的构造函数和复制控制函数。

    一个类只能初始化自己的直接基类。直接基类就是在派生列表中指定的类。

    在复制控制成员中,只有析构函数应定义为虚函数构造函数不能定义为虚函数
    即使析构函数没有工作要做,继承层次的根类也应该定义一个虚析构函数。

    与基类成员同名的派生类成员将屏蔽对基类成员的直接访问。

    纯虚函数:虚函数是一种特殊的虚函数,在许多情况下,在基类中不能对虚函数给出有意义的实现,而把它声明为纯虚函数,它的实现留给该基类的派生类去做。这就是纯虚函数的作用。在函数形参表后面写上 =0 以指定纯虚函数。


    含有(或继承)一个或多个纯虚函数的类抽象基类,除了作为抽象基类的派生类的对象的组成部分,不能创建抽象类型的对象。


    将派生类对象复制到基类对象时,派生类对象将被切掉。


    C++中面向对象编程的一个颇具讽刺意味的地方是,不能使用对象支持面向对象编程,相反,必须使用指针或引用。

    C++中可以通过定义句柄类来存储和管理基类指针。


    因为派生类对象包含基类部分,所以可以将派生类型的引用或指针转换为基类类型的引用或指针。


    第16章 模板与泛型编程


    所谓泛型编程就是以独立于任何特定类型的方式编写代码。

    函数模板是一个独立于类型的函数,可作为一种方式,产生函数的特定类型版本。


    模板定义以关键字 template 开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分隔。例如:

    template <typename T>
    int compare(const T &v1, const T &v2)
    {
       if (v1<v2) return -1;
       if (v2<v1) return 1;
    }

    可以给模板形参赋予的唯一含义是区别形参是类型新参还是非类型形参。如果是类型形参,我们就知道该形参表示未知类型,如果是非类型形参,我们就知道它是一个未知值


    类模板成员函数的定义具有如下形式:

    1、必须以关键字 template 开头,后接类的模板形参表。

    2、必须指出它是哪个类的成员。

    3、类名必须包含其模板形参。

    形式如下:

    template <class T> ret-type Queue<T>::member-name


    类模板的指针定义不会对类进行实例化,只有用到这样的指针时才会对类进行实例化。


    非类型模板实参必须是编译时常量表达式,不能用变量作模板实参。



  • 相关阅读:
    PVID和VID与交换机端口
    IO密集型和CPU密集型区别?
    Redis回收进程是如何工作的
    索引的工作原理及其种类
    drop,delete与truncate的区别
    你用过的爬虫框架或者模块有哪些?优缺点?
    列举您使用过的Python网络爬虫所用到的网络数据包
    对cookies与session的了解?他们能单独用吗
    有用过Django REST framework吗
    Django中哪里用到了线程?哪里用到了协程?哪里用到了进程
  • 原文地址:https://www.cnblogs.com/fengty90/p/3768869.html
Copyright © 2011-2022 走看看