类
类的基本思想:数据抽象(data abstraction)和封装(encapsulation)
数据抽象依赖于:接口(interface)和实现(implementation)分离的编程
引入this指针
- 成员函数可以通过一个this指针来访问调用它的那个对象
引入const成员函数
- const成员函数作用是将this声明为指向常量地指针,使得成员函数不能改变调用它的对象的内容。
7.1.4构造函数
默认构造函数
只有当一个类没有声明任何构造函数,编译器才能自动生成默认构造函数
=default
要求编译器生成默认构造函数
构造函数初始值列表
Sales_data(const std::string &s,unsigned n,double p):bookNo(s),units_sold(n),revenue(p*n){}
7.2 访问控制与封装
class默认private,struct默认public
7.2.1友元
允许其他类或者函数访问它的非公有成员
friend Sales_data add(const Sales_data&,const Sales_data&);
关键概念:封装的益处
- 确保用户代码不会无意间破坏封装对象的状态
- 被封装的类的具体实现细节可以随时改变,无需调整用户级别的代码
7.3类的其他特性
令成员函数作为内联函数
- 定义在类内部的成员函数是自动inline的
- 也可以在类外部用inline关键字修饰函数的定义
重载成员函数
和重载函数类似
可变数据成员
在成员变量声明中加入mutable关键字,使成员变量永远不会是const。一个cosnt成员函数也可以改变一个可变数据成员的值。
基于const的重载
常量对象和非常量对象通过判断对象是否是const重载了成员函数
7.3.4 友元再探
类之间的友元关系
- 友元不具有传递性
- 友元类可以访问当前类对象的私有成员
令成员函数作为友元
- 可以只把一个类的某些成员函数声明为友元类。
class screen{
frined void Window_mgr::clear(screenIndex);
};
2.步骤:
定义window_mgr类,声明但不定义clear函数。在clear使用screen成员之前先声明screen
定义screen,包括对clear的友元声明
最后定义clear
class screen;
class window_mgr
{
public:
void clear(screen &s);
};
class screen
{
friend void window_mgr::clear(screen &s);
private:
int a;
};
void window_mgr::clear(screen &s)
{
s.a=0;
}
函数重载和友元
一组重载函数声明为友元,需要对其中每一个函数进行声明
友元声明和作用域
友元声明不能替代声明,知识影响访问权限
7.5.1 构造函数初始值列表
在构造函数体中对成员变量进行“初始化”,其实是先进行默认初始化再进行赋值。
构造函数的初始值有时必不可少
当成员是const或者是引用类型的情况下,必须要进行列表初始化
列表初始化顺序是根据成员变量定义的声明的顺序保持一致
7.5.1隐式的类类型转换
只允许一步类类型转换
抑制构造函数定义的隐式转换
构造函数声明为explicit加以阻止
explicit只对一个实参的构造函数有效;需要多个实参的构造函数不能用于隐式转换
7.5.5聚合类
使得用户可以直接访问其成员,并且具有特殊的初始化语法形式。
7.6 类的静态成员
有时候类需要它的一些成员与类本身直接相关,而不是与类的各个对象保持关联。
- 静态成员存在于对象之外,对象中不包含任何静态数据成员。
- 静态成员函数也不与任何对象绑定在一起,不包含this指针。(不能声明成const,也不能使用this)
- 一旦被定义就存在于程序的整个声明周期中
- 一般类的静态成员都需要在类外初始化
- 可以为静态成员提供const整数类型的类内初始值