第二章 C++类和对象

以下是本人整理的C++基础知识点,内容并不包含全面的C++知识,只是对C++重点内容、特点进行整理和归纳。

思维导图链接:https://www.mubucm.com/doc/7E9Ilr_bznS

2.1 C++类的定义和对象的创建

类的定义
    只是一种复杂数据类型的声明,编译后不占用内存空间
    定义类时不能对成员变量进行初始化

用类创建对象
    class 关键字可省略
        class Student LiLei;  //正确
        Student LiLei;  //同样正确

访问类的成员
    栈上创建的对象  Stu stu;
        有名字,可以用点号来访问成员变量和成员函数

    堆上创建的对象(new)
        没有名字,借助指针来访问它的成员变量或成员函数
            pStu -> name = "小明";

2.2 C++类的成员变量和成员函数

类体内定义和类体外定义成员函数的区别
    类体内定义成员函数
        默认成为内联函数
        一般不是我们所期望的

    类体外定义成员函数
        不会自动成为内联函数
        建议的做法!

内联函数和非内联函数定义的区别
    内联函数
        直接在类内部定义

    非内联函数
        在类内部声明,在类外部定义

2.3 C++类成员的访问权限以及类的封装

访问限定符(限定来自外部的访问)
    public
        公开的

    protected
        受限的,在本类中使用相当于private
        在该类的派生类内部可以访问该类的protected成员

    private 
        私有的成员只能在本类内部使用,外部不能通过对象访问
        成员没有限定符,默认为 private

类的封装的意义
    封装,是指尽量隐藏类的内部实现,只向用户提供有限的、必要的成员函数
    在语法上,private 关键字能更好地隐藏类的内部实现,向外暴露的成员都声明为 public

习惯性编程规范
    成员变量:以m_开头
    限定符使用
        成员变量以及只在类内部使用的成员函数:声明为 private
        外部使用的函数:声明为public
        
    成员变量赋值的函数: set开头
    成员变量读取函数:get开头
    每一种限定符在类体中只出现一次

2.4 C++对象的内存模型

成员变量和成员函数的存储
    成员变量
        为每个对象的每个成员变量分配独立内存
        在堆区或栈区
        变量的内存顺序和声明顺序相同

    成员函数
        所有对象都共享同一段函数代码
        在代码区


对象的内存所占用的内存大小
    对象的内存组成
        仅仅包含了成员变量,不包含成员函数
            对象的大小只受成员变量的影响


    对象的内存大小
        等于成员变量占用的内存空间

2.5 C++函数编译原理和成员函数的实现

C++函数的编译
    C++函数编译时的特点
        根据它所在的命名空间、所属类、参数列表等重新命名,形成新的函数名
            新函数名只有编译器知道,对用户不可见
            编译中对函数重命名的过程叫做名字编码(Name Mangling),通过一种特殊的可逆算法实现

    编译时的名字编码
        一种特殊的可逆算法,对函数进行重新的命名,确保新函数名的唯一性


成员函数的编译和调用
    成员函数的编译
        成员函数被编译成与对象无关的全局函数
        编译成员函数时要额外添加对象指针作为参数

    成员函数和成员变量的关联
        编译被调用的成员函数时,编译器把当前对象的指针传递进去,完成关联

    通过对象调用成员函数时的隐式实现
        不是通过对象找到函数,实际上是通过函数找到对象
            因为函数调用时赋予了的当前对象的指针,关联了该对象

2.6 C++构造函数

构造函数的作用
    在创建对象的同时为成员变量赋值

构造函数的定义和声明
    声明或定义时,函数名前面不能出现返回值类型,函数体中不能有 return 语句
    构造函数必须是 public 属性的,否则创建对象时无法调用
    例子

构造函数的调用
    构造函数的调用是强制性的
        在类中定义了构造函数,那么创建对象时就一定要调用至少一个,不调用是错误的

    创建对象时提供的实参必须和其中的一个重载构造函数匹配
        创建对象时只有一个构造函数会被调用

构造函数的重载
    如果有多个重载的构造函数,那么创建对象时提供的实参必须和其中的一个构造函数匹配

默认构造函数
    如果用户没有定义构造函数,编译器会自动生成默认构造函数和复制构造函数
    如果用户定义了构造函数,编译器不会自动生成默认构造函数
    默认构造函数函数体是空的,也没有形参,也不执行任何操作
        编译器的角度:实际上编译器只有在必要的时候才会生成默认构造函数,而且它的函数体一般不为空
        默认构造函数的目的是帮助编译器做初始化工作,而不是帮助程序员

    调用没有参数的构造函数也可以省略括号
        Student *pstu = new Student()
        Student *pstu = new Student

2.7 C++构造函数初始化列表

用法
	Student::Student(char *name, int age, float score): m_name(name), m_age(age), m_score(score){...};
	
特点
    使用构造函数初始化列表并没有效率上的优势,仅仅是书写方便

成员变量的初始化顺序
    只与成员变量在类中声明的顺序有关
        先定义a,就先给a赋值
        跟初始化列表的顺序无关


初始化 const 成员变量
    初始化 const 成员变量的唯一方法就是使用初始化列表

2.8 C++析构函数

析构函数特点
    没有返回值,不需要程序员显式调用(程序员也没法显式调用),而是在销毁对象时自动执行
    析构函数没有参数,不能被重载,没有返回值
        一个类只有一个析构函数。如果用户没有定义,编译器会自动生成一个默认的析构函数


析构函数作用
    销毁对象时系统会自动调用析构函数来进行清理工作
    特别是有动态分配内存的场合,一定要自定义析构函数

析构函数的执行时机
    全局对象
        程序结束时调用析构函数

    局部对象
        函数结束时调用析构函数

    动态对象
         delete 删除时调用析构函数

2.9 C++对象数组(数组的每个元素都是对象)

    对象数组中的每个元素都需要用构造函数初始化
    构造函数有多个参数时,数组的初始化中要显式地包含对构造函数的调用

2.10 C++成员对象和封闭类

成员对象和封闭类介绍
    成员对象:一个类的成员变量是另一个类的对象
    封闭类:包含成员对象的类

封闭类对象本身的初始化
    先执行所有成员对象的构造函数
        成员对象构造函数的执行次序和成员对象在类定义中的次序一致,与构造函数初始化列表中出现的次序无关

    然后才执行封闭类自己的构造函数

封闭类成员对象的初始化
    特点
        生成封闭类对象的语句,一定要让编译器知道成员对象如何初始化,否则会编译错误
        有无参构造函数的,可以忽略其对象的初始化

    方法1:借助封闭类的初始化列表
        对于成员对象,参数表”中存放的是构造函数的参数
        通过初始化参数列表的参数,编译器就知道调用哪个初始化函数来初始化

成员对象的析构
    先执行封闭类的析构函数
    然后再执行成员对象的析构函数
        先构造的后析构
    总结:反向次序,类似于出栈过程

封闭类的构造和析构本质
    构造:入栈过程
        成员对象1,成员对象2,封闭类对象

    析构:出栈过程
        封闭类对象,成员对象2,成员对象1

2.11 C++ this指针详解

特点
    C++ 中的一个关键字,是一个指向当前对象的 const 指针,不能修改
    对象被创建后 this 才有意义,不能在 static 成员函数中使用

定义时,成员函数中的this指针存在时机
    在编译时被自动编进函数的参数列表中

调用时,this指针被赋值时机
    编译时由编译器自动完成赋值

this指针的本质
    是成员函数的一个形参,是成员函数的局部变量
    在调用成员函数时将对象的地址作为实参传递给 this
    在编译阶段发生和完成

2.12 C++ static静态成员变量

介绍
    静态成员变量是一种特殊的成员变量,被关键字static修饰,没有初始化不能使用
    所属上,static 成员变量属于类,不属于某个具体的对象
    内存上,在全局数据区分配内存,所有对象都只使用同一份内存
    static 成员变量不占用对象内存,即使不创建对象也可以访问

静态成员变量初始化(所有)
    必须要初始化
    必须在类声明的外部初始化
        type class::name = value;

    初始化不赋值,默认初始化为 0
    int Student::m_total = 10;

静态成员变量访问
    通过对象或类都可以访问
    遵循 private、protected 和 public 关键字的访问权限限制

2.13 C++ static静态成员函数

静态成员函数和普通成员函数的区别
    普通成员函数
        有 this 指针
        可以访问所有成员
        只能在创建对象后通过对象来调用
            因为需要this指针


    静态成员函数
        没有 this 指针
        只能访问静态成员变量和静态成员函数
        可以通过类来直接调用

2.14 C++ const成员变量和成员函数

const成员变量定义和初始化
    定义:声明时加上 const 关键字
    初始化:通过构造函数的初始化列表

const成员函数定义和初始化
    作用
        可以访问所有成员变量,但不能修改数值,用来保护数据
        通常将 get 函数设置为常成员函数

    const成员函数的声明和定义
        在函数头部的结尾加上 const 关键字
            char *getname() const;

        必须在成员函数的声明和定义处同时加上 const 关键字

2.15 C++ const对象

介绍
    常对象,不能修改其中的内容,所以只能调用类的 const 成员变量和 const 成员函数

常对象定义
    const  class  object(params);
    class const object(params);  //这种可能是规范的

2.16 C++友元函数和友元类

友元作用
    借助友元(friend),突破private限制,使得其它类的成员函数以及全局范围内的函数访问当前类的 private 成员

友元特点
    友元的关系是单向的
    友元的关系不能传递

友元函数
    友元函数构造
        在类外定义、在类中加上friend关键字声明,构成友元函数
        可以是非成员函数,也可以是其它类的成员函数

    友元函数特点
        可以访问当前类中的所有成员
        一个函数可以被多个类声明为友元函数

    非成员函数作为为友元函数
        声明
            void show(Student *pstu){}//在类外定义
            friend void show(Student *pstu);   //在类中声明

        访问
            友元函数需要借助对象访问
                因为友元函数不是成员函数,没有 this 指针



    将其他类的成员函数作为为友元函数
        声明
            class Address;  //提前声明Address类,并非正式声明
            friend void Student::show(Address *addr);  //类内声明

        访问
            友元函数需要借助对象访问



友元类
    特点
        将整个类声明为另一个类的朋友,所有成员函数都是另外一个类的友元函数
        除非有必要,一般不建议把整个类声明为友元类

    声明
        friend class Student;  //另一个类内声明

2.17 C++ class和struct

C/C++中struct的区别
    C中的struct
        只有成员变量,没有成员函数

    C++中的struct
        类似于class,既有成员变量,也有成员函数
        兼容C中的struct用法


C++中的 struct 和 class 的区别
     class
        类中的成员默认是 private 属性
        class 继承默认是 private 继承
        class 可以使用模板

    struct
        结构体中的成员默认都是 public 属性
         struct 继承默认是 public 继承
         struct 不能使用模板

    注意
        用法上,struct完全可以当做class来使用,但是不建议

2.18 C++ string详解

string介绍
    string 是 C++ 中常用的一个类,处理字符串更方便
    包含头文件
    没有初始化的字符串默认值是""
    string 的结尾没有结束标志'\0'

string操作
    转换为C风格的字符串
        用途
            使用C语言中的 fopen() 函数打开文件,需使用C风格的路径

        转换方法
            转换函数 str.c_str()
                将 string 字符串转换为C字符串,并返回C字符串的 const 指针(const char*)



    string 字符串的输入输出
        输入输出运算符
            输入运算符:>>
                默认会忽略空格,遇到空格输入结束

            输出运算符:<<


    字符串长度获取
        str.length();//字符串的真实长度,没有'\0'

    访问字符串中的字符
        下标访问: str[5] = '5';

    字符串的拼接
        +或+=运算符来直接拼接字符串
            string + (string , C字符串, 字符数组, 字符)

        不用担心内存溢出

    string 字符串的增删改查
        插入字符串:insert() 
        删除字符串:erase() 
        删除字符串:erase() 
        提取子字符串:substr () 
        字符串查找:find(),rfind(),find_first_of()


string的内部构造
    string 隐藏了字符序列的物理表示,使用时不必关心数组维数或\0
    string 在内部封装了与内存和容量有关的信息
        开始位置、字符序列、长度
        内存不足时,会自动调整

    C++ 标准没有定义 string 类的内存布局,由编译器本身实现,但string 类的行为表现一致

你可能感兴趣的:(C++知识点复习,c++,经验分享)