天天看点

后台开发核心技术与应用实践读书笔记(二)后台开发核心技术与应用实践读书笔记(二)

后台开发核心技术与应用实践读书笔记(二)

第2章 面向对象的C++

2.1 类与对象

  1. 概念
  2. 成员函数
  3. 封装性

    把数据和数据相关的操作封装在类里,只对可信的类或对象开放

  4. 构造函数
    1. 数据成员不能再类中初始化必须在构造函数中
    2. 类中可以定义不同的构造函数以提供不同的初始化方式(重载)
    3. 注意要在声明构造函数参数时指定默认参数值,而不是在定义中
    4. 如果定义了全是默认参数的构造函数,则不能定义重载构造函数
  5. 析构函数
    1. 函数中定义一个对象,函数调用完成时,对象会被释放
    2. static局部对象只在main与exit函数结束程序时,才会调用析构函数
    3. 全局对象与2相同
    4. new 建立的对象,delete时会调用
    注意:析构函数不是删除对象,而是释放内存以供新对象使用。当然不仅如此,还可以执行用户希望最后一次使用对象之后所进行的操作;
  6. 静态数据成员
    1. 可以把数据当成全局变量使用,但是又被隐藏在类的内部——使用静态数据成员
    2. 类的静态成员拥有一个存储区,多个对象共享这一块静态存储区,如果改变,则各个对象的这个数据成员的值都被改变了
    3. 静态数据成员类外初始化,并且不随类对象的建立与消失而改变
    4. 它在编译期间被分配空间,在程序结束释放
    5. 可以通过对象名来引用也可以通过类名来引用
  7. 静态成员函数
    1. 通过**类名::**和对象来调用
    2. 它的出现只是为了处理静态数据成员,直接引用该静态成员函数
    3. 静态成员函数没有 this指针,故不能访问本类的非静态成员
    4. 如果一定要引用该类的非静态成员函数,应加对象名,例如a.width;
  8. 对象的存储空间
    1. 空类占1个字节
    2. 静态数据成员、成员函数、构造/析构函数不占空间
    3. 如果一个类只有虚函数,则相当于含有一个指向虚函数的指针,64位8byte
    4. 函数代码是存储在对象空间之外的,而且函数代码共用
  9. this 指针
    1. 成员函数都包含的指针,指向被调用成员函数所在的对象
    2. 在成员函数开始前构造,在成员函数结束后清除,因此不能通过对象来使用this 指针
    3. 会应编译器的不同而有不同的存储位置,可能是栈、寄存器或全局变量区
    4. 普通类函数都不会创建一个函数表来保存函数指针,只有虚函数放到函数表中
  10. 类模板
    1. 多个类功能相同,数据类型不同
    2. 类外定义成员函数因写成:
      template <class T>;
      T Operation<T>::add(){
      return x+y;}
                 
    3. 函数模板是编译时自动生 成各种类型的函数实例,如同内联函数,编译时其实现必须可见,故一般其实现都必须在头文件中
  11. 析构函数与构造函数的顺序
    1. 全局对象,构造函数在所有函数之前调用(包括main);不同文件都有全局对象,则构造顺序不可知。并且在main结束或exit调用析构函数
    2. 局部对象, 局部构造与析构,多次调用多次构造析构
    3. 函数中有静态局部对象,只在程序第一次调用该函数时构造,结束也不析构,只有在main或者exit函数结束析构

2.2 继承与派生

  1. 继承性

    可以让某个类型的对象获得另一个类型的对象的属性的方法。即子类可以获得父类的属性和方法,实现了代码重用

  2. 派生类的访问属性
    1. 公有继承,基类的共用成员和保护成员保持原有属性,私有成员基类私有
    2. 保护继承,基类的共用成员和保护成员在子类中变成了保护成员,类外不可见,私有成员基类私有
    3. 私有继承,共有成员与保护成员在子类中变成私有成员,类内使用,私有成员同上面1、2
  3. 派生类的构造函数与析构函数

    对派生类的构造函数有以下说明:

    1. 基类成员与**子对象成员(指的是数据成员为一个类对象)**必须初始化列表中初始化
    2. 派生类的构造顺序:基类构造函数->子对象构造函数->派生类构造函数体
    3. 有多个基类时;调用顺序按照定义派生类时生命的顺序(自左向右),与初始化列表无关
    4. 如果派生类的基类也是派生的,只需负责直接基类的构造,依次往上
    5. 派生类有多个子对象成员,派生时按照声明的顺序(从前往后)
    6. 基类的构造函数定义了一个与多个参数时,派生类必须定义构造函数
    7. 基类中定义了默认构造函数或没有定义构造函数,派生类可以省略对基类构造函数的调用(<基类名>(<参数表>)),子对象成员也相同
    8. 所有基类或子对象的构造函数都可以省略时,可以省略基类构造函数的调用
    9. 基类与子对象构造函数都不要参数,派生类参数也不需要时,派生类构造函数可以不定义
    对于派生类析构函数:
    1. 不继承基类的析构函数,但是需要通过派生类的析构函数去调用基类的析构函数(系统来完成的)
    2. 可根据自己的需要定义自己的析构函数对增加成员进行清理
    3. 在执行派生类的析构函数时,系统会自动调用基类和子对象的析构函数;
  4. 派生类的构造函数与析构函数的额调用顺序
    1. 构造函数的调用顺序上一小节以给出
    2. 析构函数的调用顺序与构造函数正好相反
    3. 析构函数在下列3种情况下被调用
      • 对象生命周期结束时
      • delete该对象的指针,或指向对象基类类型的指针(其基类析构函数必须是虚函数),这里就是为什么基类的析构函数设定为虚函数的原因;
      • 对象i是o的成员,O被析构,i也会被析构

2.3 类的多态

  1. 多态

    多态性是指具有不同功能的函数可以使用一个函数名,在面向对象方法中:向不同的对象发送同一个消息,不同的对象在接受时会有不同的行为(即执行不同的函数)。主要体现在子类对父类函数的重写

    注意:

    1. 派生类重新定义此函数,要求函数名、函数类型、参数个数与类型全部与基类虚函数一致
    2. 定义一个指向基类对象的指针,并将它指向同一类族的对象,由此可以调用相应类中的函数
    3. 非虚函数在子类重新定义,则基类指针调用此函数则调用的是基类的成员函数,若是派生类指针则调用派生类的函数,这不是多态行为。
  2. 虚函数的使用

    使用虚函数时,系统具有一定的空间开销。当一个类带有虚函数时,编译系统会为之分配一个虚指针。系统在动态关联时的时间开销是很少的。因此多态是高效的

  3. 纯虚函数
    1. 基类没有定义,原型后加“=0”,这是因为基类本身生成的对象是不合理的,比如动物这个基类
    2. 子类一定要实现,否则编译出错
  4. 析构函数
    1. 构造函数不能声明为虚函数原因
      1. 编译器构造对象在构造时必须知道确切类型
      2. 构造之前,对象不存在,无法使用指向此对象的指针来调用构造函数
    2. 析构函数声明为虚函数原因

      C++明确指出**:子类对象由父类指针删除,而基类即析构函数是非虚的,会导致对象的子类成分没有析构掉,这样容易引发内存泄漏**

  5. 单例模式

    单例模式的要点有三个:

    • 单例类有且仅有一个实例
    • 单例类必须自行创建自己的唯一实例
    • 单例类必须给所有其他对象提供这一实例
    懒汉式单例模式
    class CSingleton
    {
    private:
        CSingleton() //构造函数是私有的
        {
        }
        static CSingleton *m_pInstance;
    public:
        static CSingleton * GetInstance()
        {
            
            if(m_pInstance == NULL) //判断是否第一次调用
                m_pInstance = new CSingleton();
            return m_pInstance;
        }
    };
               
    线程安全单例模式
    // 线程安全的单例模式
    class Singleton
    {
    private:
    	Singleton() { }
    	~Singleton() { }cpp
    	Singleton(const Singleton &);
    	Singleton & operator = (const Singleton &);
    public:
    	static Singleton & GetInstance()
    	{
    		static Singleton instance;
    		return instance;
    	}
    };
               

索引

  1. 第 1 章 C++常用的编程技术
  2. 第 2 章 面向对象C++
  3. 第 3 章 常用的STL使用
  4. 第 4 章 编译
  5. 第 5 章 调试
  6. 第 6 章 TCP协议
  7. 第 7 章 网络IO模型
  8. 第 8 章 网络分析工具
  9. 第 9 章 多线程
  10. 第 10 章 进程
  11. 第 11 章 进程间通信
  12. 第 12 章 HTTP协议

继续阅读