- 使用类定义自己的数据类型
- 本章主要关注数据抽象→将对象的具体实现与对象所能执行操作分离开来
零、术语表
- 聚合类
- 类:C++提供的自定义数据类型的机制。类可以包含数据、函数和类型成员。一个类定义一种新的类型和一个新的作用域
- 类的作用域:每个类定义一个作用域,类中定义的成员函数可能使用定义语句之后的名字。
- 常量成员函数:修改隐式this参数为指向常量的常量指针,从而使得该成员函数可以由常量对象调用,同时,在其中不能修改对象的普通数据成员
- 构造函数初始值列表:在构造函数体执行之前首先用初始值列表中的值初始化数据成员。未经初始值列表初始化的成员将被默认初始化
- 显示构造函数:可以用一个单独的实参调用但是不能用于隐式转换的构造函数,explicit
一、定义抽象数据类型
1.设计sales_data类
- 定义改进的sales_data类
- 引入this:
- 成员函数通过一个名为this的额外的隐式参数来访问调用它的对象,用求求该函数的对象地址初始化this
- this的目的总是指向“这个”对象,所以this是一个常量指针
- 引入const成员函数→常亮成员函数
- string isbn() const {return this->bookNo;}
- const的作用是修改隐式this指针的类型→由指向非常量对象的常量指针改为指向常量对象的常量指针
- 常量成员函数不能改变对象的内容
- 定义类相关的非成员函数
- 构造函数
- 初始化类对象的数据成员,无论何时只要类的对象被创建,就会执行构造函数
- 默认构造函数→无实参的构造函数
- 合成默认构造函数→编译器创建的构造函数
- 如果存在类内初始值,则用类内初始值初始化
- 否则,默认初始化
- 只有当类没有声明任何构造函数时,编译器才会自动的生成默认构造函数
- 有些类的默认构造函数可能会执行错误的操作→定义在块中的内置类型或者复合类型(如数组和指针)的对象被默认初始化→同样适用于默认初始化的内置类型成员→如果类中包含有内置类型或者复合类型成员,只有当这些成员全都被赋予了类内初始值,才能对该类使用合成默认构造函数
- =default→要求编译器生成构造函数→如果=default在类的内部,则默认构造函数是内联的,否则不是内联的??
- 初始值列表:按照数据成员在类中出现的先后顺序初始化
- 拷贝、赋值和析构
- 拷贝:初始化变量或者传值参数或者返回一个对象
- 赋值:使用赋值运算符
- 析构:对象不再存在时执行销毁的操作:
- 局部对象会在创建它的块结束时被销毁
- vector对象被销毁时,存储在其中的对象也会被销毁、
- 合成版本:对对象的每个成员执行拷贝、赋值和销毁操作
二、访问控制与封装
- 访问控制:public、private
- 封装的优点:
- 确保用户代码不会无意间破坏封装对象的状态
- 被封装的类的具体实现细节可以随时改变,而无需调整用户级别的代码。
- 友元
- 类可以允许其他类或者函数访问它的非公有成员,方法是令其它类或者函数成为它的友元
- friend关键字开始的函数声明语句
三、类的其它特性
- 类成员再探
- 类类型成员:类可以自定义某种类型在类中的别名
public:
typedef std::string::size_type pos;
- 返回*this的成员函数
- 类类型
- 友元再探
四、类的作用域
五、构造函数再探
- 构造函数初始值列表
- 直接初始化数据成员 VS 先初始化再赋值→尽量选择前者
- 构造函数的初始值有时必不可少
- 引用
- const 成员
- 某些没有默认构造函数的类
- 按照在类中定义的顺序初始化
- 委托构造函数
- 默认构造函数的作用
- 当对象被默认初始化或者值初始化时自动执行默认构造函数
六、类的静态成员
- 作用:类的静态成员存在于任何对象之外
- 对象中不包含任何与静态数据成员有关的数据
- 静态成员函数不与任何对象绑定在一起,不包含this指针
- 使用:
- 使用作用域运算符直接访问
- 使用类的对象、引用或者指针来访问
- 成员函数直接使用
- 一般来说,不能在类的内部初始化静态成员,必须在类的外部定义和初始化每个静态成员
- 一旦被定义,就一直存在于程序的整个生命周期中
网友评论