抽象是一种认识事物的本质
image.png

类:从对象中抽离出来的抽象
对象:具体的事物

  1. /**
  2. * 类的定义
  3. */
  4. class Dog{
  5. char name[20];
  6. int age;
  7. int type;
  8. void speak(){};
  9. void run(){};
  10. };

访问限定符

public: 公共的
protected: 受保护的
private: 私有的

对象的实例化

1.栈中创建

  1. Dog dog;
  2. Dog dog2[20];

2.堆中创建

  1. Dog *dog = new Dog();
  2. Dog *dog2 = new Dog[20];
  3. //对象用完需要释放掉内存
  4. delete dog;
  5. delete []dog2;

对象成员的访问

栈中实例化对象成员的访问

  1. dog.age;
  2. dog.speak();

堆中实例化对象成员的访问

  1. dog -> age = 10;
  2. dog -> speak();
  3. for (int i = 0; i < 20; i++) {
  4. dog2[i].age = 20;
  5. dog2[i].speak();
  6. }
  7. //堆中实例化的对象可能失败,使用之前需要判空

字符串string引入

  1. #include <string> //需要先引入string头文件
  2. string name = "zhangsan";
  3. string name(zhangsan);

初始化方式

  1. string s1; //s1为空串
  2. string s2("ABC"); //用字符串字面值赋值
  3. string s3(s2); //用s3初始化为s2的副本
  4. string s4(n, 'c'); //将s4初始化为字符'c'的n个副本

常用操作

  1. s.empty();
  2. s.size();
  3. s[n];
  4. s1 + s2;
  5. s1 = s2;
  6. s1 == s2;
  7. s1 != s2;
  8. //getline(cin, name) //获取用户输入

封装

屏蔽属性的直接访问,通过方法访问,方法里面可以加部分业务,外部可以直接访问到方法,达到间接访问属性的目的

  1. class Student{
  2. public:
  3. void setAge(int age){
  4. m_iAge = age;
  5. };
  6. string getName(){
  7. return m_strName;
  8. };
  9. private:
  10. string m_strName;
  11. int m_iAge;
  12. };

类内定义和内联函数

内联函数:编译时将函数体代码和实参代替函数调用语句,适用结构简单的函数,关键字inline
类内定义:在类中定义的方法

类外定义

成员函数体写在类外部

同文件类外定义:函数体和类定义在同一个文件中

  1. class Dog {
  2. public:
  3. char name[20];
  4. int age;
  5. int type;
  6. void speak();
  7. void run();
  8. };
  9. void Dog::speak() {};
  10. void Dog::run() {};

分文件类外定义:函数体和类定义不在同一个文件中,这种方式一般比较常用

  1. //Car.h
  2. class Car{
  3. public:
  4. void run();
  5. void stop();
  6. void changeSpeed();
  7. };
  8. //Car.cpp
  9. #include "Car.h"
  10. void Car::run() {}
  11. void Car::stop() {}
  12. void Car::changeSpeed() {}

内存分布

栈区:分配的内存不需要手动释放
堆区:分配的内存需要手动释放
全局区:存储全局变量及静态变量
常量区:string str = “hello world”;
代码区: 存储逻辑代码的二进制,编译后的代码

构造函数

在对象实例化时候被自动调用
与类同名
没有返回值
可以有多个重载
实例化对象时候仅用到一个构造函数
用户没有调用时候,编译器自动生成一个构造函数

  1. class Student{
  2. public:
  3. Student(){
  4. };
  5. Student(int age, string name){
  6. };
  7. };
  8. Student student;
  9. Student student1(10, "hehe");
  10. //构造函数定义的时候,可以直接定义默认值

初始化列表

特性:
1.先于构造函数执行
2.只能用于构造函数
3.可以同时初始化多个数据成员

必要性:
使用const修饰的变量必须要用初始化列表

  1. class Student{
  2. public:
  3. Student(){
  4. };
  5. Student(int age, string name): m_strName(name), m_iAge(age){
  6. }
  7. void setAge(int _age){
  8. m_iAge = _age;
  9. };
  10. string getName(){
  11. return m_strName;
  12. };
  13. private:
  14. string m_strName;
  15. int m_iAge;
  16. };

拷贝构造函数

  1. Student(){
  2. cout << "Student()" << endl;
  3. };
  4. Student(const Student& student){
  5. cout << "Student(const Student& student)" << endl;
  6. }
  7. //实例化时候,student2和student3会自动调用拷贝构造函数
  8. Student student1;
  9. Student student2 = student1;
  10. Student student3(student2);

1.如果没有自定义的拷贝构造函数则系统自动生成一个默认的拷贝构造函数
2.当采用直接初始化或复制初始化实例化对象时系统自动调用拷贝构造函数

析构函数

格式:~类名()

  1. //析构函数不允许加参数
  2. ~Student(){
  3. cout << "~Student" << endl;
  4. }

1.如果没有自定义的析构函数则系统自动生成
2.在对象销毁时候,会被自动调用,用来释放内存
3.析构函数没有返回值,没有参数也不能重载

对象生命历程

申请内存 -> 初始化列表 -> 构造函数 -> 参与运算 -> 析构函数 -> 释放内存