一、封装
封装本身是围绕着类进行的:在类中写各种各样的函数
1、类
在C++中创建类的函数有两个,分别是struct 和 class
struct 和 class 创建的叫类,使用 类 定义的变量叫做 对象,类中的变量叫做 成员变量
1)类 中对象的访问权限
piblic:公开权限 在类 内部,外部均可访问
protected:受保护权限 在类 内部可以访问,外部不可访问
private:私有权限 在类 内部可以访问,外部不可访问
目前来说 private 和 protected 这两个权限没有区别
private 和 public 具体使用
根据 c++ 标准委员会的要求(人为规定):没有特殊需求的时候,
所有的成员属性(变量),都放在private里面,所有成员方法(函数) ,都放在public里面
2)内部访问和外部访问
外部访问:
既不在类的作用域中访问成员属性,并且在访问的时候,前面也没有加上 作用域:: 运算符,都属于外部访问
内部访问:
和外部访问相反,只要在类的作用域里面,或者访问的时候,前面有 作用域::运算符,都属于内部访问
3)struct 和 class 的区别
创建类:
struct 创建的类,中的参数,默认是piblic(公开权限)
class 创建的类,中的参数,默认是private(私有权限)
初始化类:
class 不允许直接使用 {} 形式进行初始化 (如果想要使用{} 初始化,需要额外操作)
4)类 的初始化方式
类 的初始化要通过 构造函数 初始化
2、构造函数
构造函数是类中和类同名的函数,如果类中没有构造函数,编译器会自动添加无意义的构造函数
无论是创建 class对象,还是创建 struct对象,只要是定义类的对象都会自动调用类内的构造函数
1)构造函数的特点
1. 构造函数没有返回值类型
这里的没有返回值类型不是指void,而是实实在在的没有返回值类型
2. 函数名必须和类名一致
3. 自动添加空的析构函数
如果类中没有写构造函数编译器会自动补全一个内容为空的、无参无返的 构造函数
4. 构造函数允许出现多个(形参类型不完全一致)
形参类型不完全一样:参数、数量、排列组合的顺序,只要有一个不一样
当有多个版本的构造函数的时候,到底调用的是哪个版本的构造函数,取决于调用构造函数的时候,传递了什么排列组合的实参
2)构造函数的调用方式
1. 自动调用
格式:
类名 对象(参数1,参数2···)
2. 手动调用
格式:
类名 对象=构造函数名(参数1,参数2···)
3. 隐式调用
格式:
类名 对象(单个参数)
注意:如果填写了多个参数,由于逗号运算符,只获取最后一个变量的值
格式:
类名 对象={参数1,参数2···}
3)隐式调用
上述的方法中有两种被称为隐式调用,隐式调用就是我们无法直接看出调用了类的构造函数
可以通过在函数的声明前添加关键字 explicit 用于禁止隐式调用
隐式调用的示例:
隐式调用赋值
4)初始化列表
构造函数分为两个部分:内核部分和用户部分
用户部分:{}内的部分,负责执行用户自己编写的代码
内核部分:()到{}中间的部分,申请该对象所需要的所有栈空间
这部分区域,用户是可以人为干涉的
: 变量名1(初始值),变量名2(初始值),...,对象1(构造函数参数),对象2(构造函数参数),......
在列表初始化里面,()前面的一定是成员属性,()里面的就近原则
3、对外接口
对外接口:专门用来访问私有成员的公开函数就是对外接口
这种形式的好处在于,开发者对私有成员拥有着绝对的控制权
如果开发者希望使用者能够访问某个私有成员,那么直接提供私有成员的接口即可
关于接口访问私有成员有两个访问形式 读访问 写访问
所以我们也需要两个接口进行这两种访问 get接口(读访问) set接口(写访问)
4、C++中const关键字
封装接口练习:
封装一个mystring类,
class mystring{
private:
//char buf[256];
char* buf;// 指向一个堆空间,该堆空间用来保存外部传入的字符串
int len; // 记录 buf里面保存的字符串有多少
public:
};
要求能够实现以下功能
int main(){
mystring str = "hello"; // 这段代码要求一定为mystring类写一个可隐式调用的单参构造函数
mystring ptr = "world"; // 在写单参构造函数的时候,私有成员len使用列表初始化的形式初始化
str.copy(ptr);
str.copy("你好");
str.append(ptr)
str.append("你好")
str.compare(ptr)
str.compare("你好")
str.show(); // 最后再写一个 show 函数,用来在终端输出 str 里面保存的字符串
cout << str.at(0) << endl;// 再写一个 at 函数,用来输出 str中第0个字符
}
5、C++中的this指针
this指针一直存在:所有对象调用成员函数的时候,成员函数的形参中永远存在this指针
当对象调用成员函数时,编译器会默认,在函数调用传参的最左侧,多传入一个实参,
该实参就是,调用成员函数的对象地址,也就是this指针。在声明部分也是同理。
6、析构函数
析构函数:是当对象生命周期结束时,自动调用的函数
构造函数在创建对象时自动调用;析构函数在销毁对象时自动调用
1)析构函数的特点
1. 析构函数没有返回值类型
2. 函数名必须和类名一致
3. 自动添加空的析构函数
4. 手动调用析构函数
2)析构函数的作用
7、引用(新的数据类型)
引用时C++中出现的一种新的数据类型,其功能和地位和C语言中的指针类似
1)引用的写法
int a = 10;
int& pa = a;
所以引用的语法就是: 数据类型& 引用变量名 = 被引用的数据
2)引用的作用
3)引用的特点
1. 普通引用和常量引用
变量,可以使用 普通引用 或 常量引用 进行绑定
常量,必须使用 常量引用 进行绑定
2. 引用只要在初始化时,可以绑定对象
所以引用必须初始化,初始化后的所有 等号 都是被绑定的数据赋值,而不是更换绑定
3.
4)引用和指针的区别
8、拷贝构造函数
1)拷贝构造函数的特点
1. 构造函数所具有的特点,拷贝构造函数都有
2. 如果没有写拷贝构造函数,编译器就自动补全一个拷贝构造函数
3.