第7章 类

  • 使用类定义自己的数据类型
  • 本章主要关注数据抽象→将对象的具体实现与对象所能执行操作分离开来

零、术语表

  • 聚合类
  • 类:C++提供的自定义数据类型的机制。类可以包含数据、函数和类型成员。一个类定义一种新的类型和一个新的作用域
  • 类的作用域:每个类定义一个作用域,类中定义的成员函数可能使用定义语句之后的名字。
  • 常量成员函数:修改隐式this参数为指向常量的常量指针,从而使得该成员函数可以由常量对象调用,同时,在其中不能修改对象的普通数据成员
  • 构造函数初始值列表:在构造函数体执行之前首先用初始值列表中的值初始化数据成员。未经初始值列表初始化的成员将被默认初始化
  • 显示构造函数:可以用一个单独的实参调用但是不能用于隐式转换的构造函数,explicit

一、定义抽象数据类型

1.设计sales_data类

  1. 定义改进的sales_data类
  • 引入this:
    • 成员函数通过一个名为this的额外的隐式参数来访问调用它的对象,用求求该函数的对象地址初始化this
    • this的目的总是指向“这个”对象,所以this是一个常量指针
  • 引入const成员函数→常亮成员函数
    • string isbn() const {return this->bookNo;}
    • const的作用是修改隐式this指针的类型→由指向非常量对象的常量指针改为指向常量对象的常量指针
    • 常量成员函数不能改变对象的内容
  1. 定义类相关的非成员函数
  2. 构造函数
  • 初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数
  • 默认构造函数→无实参的构造函数
  • 合成默认构造函数→编译器创建的构造函数
    • 如果存在类内初始值,则用类内初始值初始化
    • 否则,默认初始化
    • 只有当类没有声明任何构造函数时,编译器才会自动的生成默认构造函数
    • 有些类的默认构造函数可能会执行错误的操作→定义在块中的内置类型或者复合类型(如数组和指针)的对象被默认初始化→同样适用于默认初始化的内置类型成员→如果类中包含有内置类型或者复合类型成员,只有当这些成员全都被赋予了类内初始值,才能对该类使用合成默认构造函数
  • =default→要求编译器生成构造函数→如果=default在类的内部,则默认构造函数是内联的,否则不是内联的??
  • 初始值列表:按照数据成员在类中出现的先后顺序初始化
  1. 拷贝、赋值和析构
  • 拷贝:初始化变量或者传值参数或者返回一个对象
  • 赋值:使用赋值运算符
  • 析构:对象不再存在时执行销毁的操作:
    • 局部对象会在创建它的块结束时被销毁
    • vector对象被销毁时,存储在其中的对象也会被销毁、
  • 合成版本:对对象的每个成员执行拷贝、赋值和销毁操作

二、访问控制与封装

  • 访问控制:public、private
  • 封装的优点:
    • 确保用户代码不会无意间破坏封装对象的状态
    • 被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码。
  • 友元
    • 类可以允许其他类或者函数访问它的非公有成员,方法是令其它类或者函数成为它的友元
    • friend关键字开始的函数声明语句

三、类的其它特性

  1. 类成员再探
  • 类类型成员:类可以自定义某种类型在类中的别名
public:
 typedef std::string::size_type pos;
  1. 返回*this的成员函数
  2. 类类型
  3. 友元再探

四、类的作用域

五、构造函数再探

  1. 构造函数初始值列表
  • 直接初始化数据成员 VS 先初始化再赋值→尽量选择前者
  • 构造函数的初始值有时必不可少
    • 引用
    • const 成员
    • 某些没有默认构造函数的类
  • 按照在类中定义的顺序初始化
  1. 委托构造函数
  2. 默认构造函数的作用
  • 当对象被默认初始化或者值初始化时自动执行默认构造函数

六、类的静态成员

  • 作用:类的静态成员存在于任何对象之外
    • 对象中不包含任何与静态数据成员有关的数据
    • 静态成员函数不与任何对象绑定在一起,不包含this指针
  • 使用:
    • 使用作用域运算符直接访问
    • 使用类的对象、引用或者指针来访问
    • 成员函数直接使用
  • 一般来说,不能在类的内部初始化静态成员,必须在类的外部定义和初始化每个静态成员
  • 一旦被定义,就一直存在于程序的整个生命周期中

你可能感兴趣的:(第7章 类)