C++ 大学课堂知识点总结

一、从C到C++
1.引用
int b;
int &a = b;//a是引用类型       定义的时候加&  表示引用   其余都是取地址 
a是b别名 使用a和使用b是一样的  主要用于函数传参
引用和指针的区别:
引用 相当于外号  不占内存   引用是常量   定义的时候就一定要赋值   不能修改指向
指针  指针变量  存放的是地址  占内存  定义的时候并需要赋值
引用 主要在函数传递参数  提高效率  效率高于指针
int &a = b;//定义的时候  是引用
&a;//取地址
C++也有指针
2.函数部分
 函数 作用 : 代码封装-->减少重复代码     划分模块 便于维护
 函数调用的时候-->函数跳转(需要时间)
 2.1内联
  关键字  inline    内联函数-->    #define  M(a, b) ((a)+(b))
  内联和带参宏定义相似   通过代码复制(浪费内存)   减少函数跳转所需要的时间   空间膨胀换时间
  内联  函数  用起来和函数一样   适用于短的函数  并且常用的函数
  长的函数  循环  函数调用 不适用于内联
  带参宏定义什么时候用 ? -->内联什么时候用
  内联-->替换带参宏定义
  相对于 带参宏定义的好处     参数有类型   不需要考虑优先级  直接当函数使用

 2.2 重载  函数名 相同   参数不一样
  C++允许函数同名   参数不一样(1.参数个数  2.类型)
  a + b-->  int fun(int a, int b)
  double fun2(double a, double b)
   -->int fun(int a, int b)
    double fun(double a, double b);
  一个函数名实现相近多个功能  调用函数的时候通过参数区分
  仅返回值不同不构成重载
  计算机通过参数类型区分调用哪个函数

 2.3 缺省
  定义函数的时候给参数设定默认值   调用函数的时候 这个参数可以省略
  函数定义的时候能不能缺省 ? 能
  函数定义的时候在参数里面写
  如果函数有声明 有定义   只需在声明中缺省
  缺省  只能从右往左缺省(允许全部缺省)
  -->重载和缺省    二义性问题
  调用的时候 不确定调用哪个函数-->二义性(重载和缺省同时使用的时候)
4.new delete
 -->new 申请 内存   malloc
 --->delete 释放内存   free
 申请10个int大小的空间
  int *p = (int*)malloc(sizeof(int)* 10);//C语言
  free(p);//C语言的内存释放
  int *p = new int[10];//C++的内存申请   10个int  
  delete[] p;//释放内存  []放delete后面  []里面不需要加数字   delete[]  p;
  int *q = new int;//申请一个int
  delete q;//释放内存
  int m = 10;
  int *p = new int[m];//申请的时候[]里面的数字是多少个变量   m个int的大小的空间 
  struct node{};
  struct node*p = new node;//申请内存
5.简单的输入输出
 cin   cout     输入输出   endl   换行
 cin >>
 cout <<
 cin >> 不需要加取地址
C++兼容C   然后C语言不能使用C++的
二、面向对象
1.面向对象的思想
 面向过程   1.创建界面  2.生成地图  3.贴图 4.用户点击 5.判断
 以函数为中心
 面向对象  用对象描述-->对象-->数据为核心
 抽象  封装  继承  多态
2.类和对象
 C语言 结构体
 struct student
 { 
  //成员变量
 };
 C++的类
 class student
 {
  //成员变量
  //成员函数
 };
 对象用.对象指针 ->
 对象(数据 行为 保密的)--->   权限问题
 public  公有 外部可以直接访问  所有人都可以用
 private  私有  类的内部进行访问  但是外部不能访问
 protected 受保护的  和私有类似
 类中的成员变量 成员函数 默认私有
 数据方面 一般写成私有   函数 公有
 成员函数中都有一个this指针(和普通函数区别)  指针指向当前对象
 区分参数和成员(如果参数名和成员名不一样  那么可以省略this指针)
 //成员变量 私有  -->在外部调用公有的成员函数给成员变量赋值
 类的成员函数并不是一定要在类里面定义 可以在类外定义 在类里面声明
3.类和结构体的区别和联系
 C++ 的结构体中可以有成员函数(C语言结构体不行) private / protected / public   C++结构体定义变量的时候不需要加struct关键字
 struct student pointer;
 C++类
 区别  结构体成员默认公有    类的成员默认私有
 结构体 一般只用来存放数据   类中有函数
 理解类的本质-->结构体 公有的类   类就是私有的结构体
 C++结构体中也可以写函数
 对象大小只和成员变量的大小有关
三、构造析构拷贝
1.构造函数
 函数给对象成员初始化-->构造函数(构造器)
 构造函数 1.和类名相同 2.没有返回值类型  也没有返回值  3.调用构造的方式 对象出生自动调用(只会调用一次)
 类中成员 没办法在类外访问->使用的时候赋默认值 初始化
 函数名和参数-->重载 缺省
2.析构函数
 析构函数   释放资源(比如说类中的指针 申请内存  交给析构释放_)
 析构函数名   ~类名  没有返回值类型, 没有参数 自动调用(对象销毁的时候调用)
 系统提供的默认构造(没有参数)和析构(不会做任何事情)
3.new delete     malloc free
 new 调用构造  malloc不会
 delete 调用析构  free不会
 delete[] 调用所有对象的析构函数
4.const成员和初始化形参列表-->给变量赋值
 const  常属性     只能通过初始化形参列表赋值
 初始化形参列表的写法
 初始化形参列表可以给const成员赋值 也可以给普通成员变量赋值
5.static 成员
 不属于某个对象  属于整个类
 这个类的所有对象共用static属性成员
 类--> class --->定义的变量叫做对象  作用域:全局
 * 设定初值  类外赋值
6.拷贝构造
 1.类-->提供4个默认函数
 默认构造函数(没有参数的构造函数)
 析构函数
 拷贝构造
 赋值函数
 拷贝构造  特殊的构造函数-->参数只有一个  是这个类类型的参数
 *调用时机    1)定义对象的时候    A a(A类型的对象)
    2)定义对象的时候  用 = 初始化   A  a = A类型的对象;
    3)隐性调用   传递参数  形参拷贝实参
 注意的点 : 1.参数必须为引用类型    (如果不使用引用  那么传参的过程会调用拷贝构造)
     2.拷贝构造中  单独申请内存-->深拷贝
     没有单独申请内存-->浅拷贝
     浅拷贝-->两个指针指向同一个区域  释放内存会出问题
     默认的拷贝构造是浅拷贝
     对象传递参数  引用  没有新的对象产生
     没有写引用   有一个临时对象
     对象 一般传参都会传递引用
 2.const成员(成员变量 / 成员函数)
    const   常属性  const int x定义必须赋初值  赋值之后不能修改
   类中的const成员变量  赋值初始化形参列表赋值
    const成员函数  在成员函数后面加const 里面不能修改类成员变量的值
   不能调用其他非const成员函数
    const加在函数前面 修饰返回值类型
    const加在函数的括号里面  修饰 参数类型
    引用 提高效率  可以在函数中通过引用修改实参的值
    传递const引用 可以避免在函数修改实参的值
    --> const int*和 int*const
     const int*p   常量指针   *p的值不可以修改但指向可改变//int const *p
    int*const q    指针常量   q的值能修改但q不能改指向
  3.static成员(成员变量 / 成员函数)
    1)修饰全局变量   不能在外部文件访问(extern指明访问访问其他cpp的变量)
    2)修饰函数里面的变量  只会定义一次(静态存储区 函数调用结束先不释放)
    3)修饰成员变量   static成员变量  不属于单个对象 属于整个类(赋初值  要在类外赋初值)
    4)修饰成员函数  也是属于这个类     只能修改静态成员
    (static修饰成员函数  没有this指针)
四、运算符重载
 1.友元
  数据--->私有   不能在类外访问  安全性
  访问里面数据的时候-->通过函数访问      速度慢
  针对常用的,需要使用类中私有成员的函数-->友元
  友元  可以访问类中 的私有成员
  friend 关键字  放在函数前面-->破坏数据封装性
  类中成员   私有成员-->只能类中成员函数  友元函数访问
  公有成员-->所有函数都能访问
  友元函数  是类的成员函数么 ? 不是
  友元的优缺点
  友元 外部访问私有成员的机制
  通过成员函数访问私有成员-->友元提高 运行效率
  缺点 破坏数据的封装性 导致程序的可维护性变差
  友元函数:将一个函数声明成一个类的友元   这个函数可以访问类的私有成员
  友元类:将一个类A声明成另外一个类B的友元   这个A中所有成员函数可以访问类B的私有成员
   A是B的朋友  B是不是A的朋友 ?              不是
    我把你当朋友  你把我当(...自行脑补)
   A是B的朋友  B是C的朋友   A是不是C的朋友 ? 不是
    ---> 友元类 不能传递
  类的私有属性-->类中成员的访问方式
  私有成员不能在类外访问  不影响友元
  友元的声明和定义可以放在类中的任何位置
  关于  友元类使用   一般不会用到
  类中的函数  声明成另外一个类的友元
 
 2.运算符重载
  运算符  基本数据类型使用运算符-->在自己定义的对象之间使用运算符
   PS:运算符重载不是一定要写  写了之后可以实现在自己的对象之间使用运算符操作
  不能重载的运算符 .  ::   .*  sizeof  三目运算符
  访问对象中的数据 1.成员函数  2.友元函数  --->a + b
  operator运算符(参数)
  运算符重载 函数参数个数必须和操作数个数一致
  函数的实现 不要违反运算规则
  优先级问题:重载时候不要改变优先级顺序
  不可以创造新的运算符
  单目--->推荐成员函数
  双目-->推荐写友元函数  两个参数可以交换顺序
  (1)算数运算符 + -*/ %
  (2)关系运算符 == != >  < >= <= 双目运算符
  (3)逻辑运算符 && || !
  (4)自增 自减(前++  后++)
  (5)位运算符
  (6)赋值运算符 += -= (= 额外讲)
  (7) ()[] * &  ->
   ()-->   A  a;   a();//调用的重载()运算符     函数调用 函数名(参数)
    重载()的目的  让这个对象更像函数       仿函数  对象-->模仿函数
     仿函数--->实现方式 运算符重载  重载()
     对象名(参数)  仿函数   调用方式和函数形式一样
     1)仿函数 参数  仿函数 返回值
      构造  在对象出生时调用   只会调用
      仿函数 在对象出生之后调用  想调用几次就调用几次
      //   返回值类型   operator() (参数)
      回调函数-->仿函数
      []-->       string-->里面存了字符串   string  st("hello");  假装是数组  char*
      -->st[3]-->'l'
      重载[]   对象中放数组 / 指针(申请动态数组)  int数组
 
      *   里面有指针
      &   返回某个成员的地址
      ->  里面有结构体 / 对象  成员   返回结构体 / 对象的地址  struct
  (8)new delete
   new运算符  三个操作
   1)operator new   (可以重载的部分)主要作用 分配内存
   2)调用构造函数
   3)返回一个指针
   delete 两个操作
   1)调用析构
   2)释放内存  operator delete (可以重载的部分)
   operator new    成员函数  分配内存 new  调用的时机还没有对象  只能static  全局   不能成员(想想前面讲到的static)
  *  operator new() 和 operator delete() 是隐式的static成员。因此,它们无法使用this指针,也不能修改对象的值。一般不建议改写。
五、继承
 继承  从已有类中加上属性(成员变量)和方法(成员函数)定义一个新的类型
 已有类  基类 / 父类          新的类   派生类 / 子类
 父类派生子类   子类继承父类
 1.继承   子类得到父类的所有成员和所有函数(不包括构造和析构)
 2.调整
  2.1访问控制
   父类的成员访问权限   public          private   protected
   继承方式
   public    public                    不可访问   protected
   private    private       不可访问      private
   protected    protected      不可访问      protected
                                                      (子类成员的访问权限)
   继承方式  默认私有
   父类 成员属性--->继承方式不同--->继承到子类中 在子类中的表现不一样
     父类的私有成员在子类中不能访问
   子类继承过来的父类的成员函数去访问
   protected 子类继承过来可以访问
   private 子类继承过来不能访问
  2.2  隐藏  子类存在和父类的同名的成员(变量/函数)  子类优先使用子类的成员
   父类的成员得到隐藏
   想要访问父类的同名函数  用类名
  2.3 添加新成员 子类   添加新功能 添加新成员变量/成员函数--->实现新的功能
 
 3.多继承   多个父类派生一个子类(C++有 其他语言没有)
 多继承怎么写
 子类拥有所有父类中所有的成员
 4.关于多继承中
  多个父类有同名成员变量   成员函数(参数)
  子类中新定义的成员和父类成员同名(隐藏)
 5.菱形继承问题
  A派生B和C   B和C共同派生D   D有两份来自爷爷中的成员
  解决菱形继承方法-->虚继承   virtual
  //解决方案 让B和C  虚继承A(两个子类都要virtual)
  //实现的机制
  孙子类  就一份来自祖父类的拷贝
  菱形继承--->影响的是哪个类  孙子类
  虚继承--->解决菱形继承的问题---->孙子类
  虚继承需要写在father中
  A(x, y)-->B(A(x1, y1), z)   C(A(x2, y2), z)
  B + C---->D(B(A(x, y), z), C(A(x, y), z), z) 菱形继承
 
  虚继承-->D(B(z), C(z), A(x, y), z)//  B::z   C::z  z
  PS:这里还涉及到一个知道点----偏移量,有兴趣先自己去了解,暂时不做讲解
六、多态
  多态  一种形式 多种状态
  想想USB接口   每种线功能不一样-->多态
  父类的指针 可以指向子类对象  什么类的指针 调用什么类的函数
  一个基本保证:一个指针永远不应指向这样的对象——不能提供指针所承诺的最基本的属性
  目的  通过父类的指针调用子类的函数  实现方式:虚函数
  virtual 虚函数  在父类的函数名前面加上virtual  子类中重写父类的虚函数(函数名相同 参数一样)
  覆盖  子类重写父类的虚函数 父类的函数得到覆盖(用父类指针调用  调用的也是子类函数)
  隐藏  子类重写父类的函数   父类的函数得到隐藏
  虚函数-->根据对象决定调用什么函数
  父类 虚函数-->没必要写 父类虚函数  不写实现 直接函数后面写上 = 0   纯虚函数
   //virtual void eat() = 0;// 纯虚函数
  *一个有纯虚函数的类(虚类 / 抽象类 / 接口类) 没办法定义对象 只能定义指针
  *如果子类继承了父类的纯虚函数  然后没有实现  那么这个子类也是虚类  不能创建对象
  构造和析构    构造(不用管)
  析构    建议写虚析构
  //知道虚表存在-->多出一个指针大小   //涉及偏移量
  //虚函数    类中定义了新的虚函数   类中会多出来一个指针(虚表指针)
  虚函数访问方式  通过虚表访问
  实现多态的方式   子类通过重写  修改虚表中函数的地址
  father*p = new son-->p能访问到的内容  1.father的成员函数   2.son的成员(继承过去的成员)
  继承-->子类重写父类的函数(成员函数)
  虚函数 1.成员函数
    2.不能是静态成员函数
    3.不能是内联函数(会处理成非内联函数)  inline (PS: 类中实现的成员 默认处理成内联函数)
    4.构造不能为虚函数   析构一般写虚函数
补充:
1.对象什么时候结束生命周期 
 作用域{}   出了作用域,对象结束生命周期
2.析构只释放构造函数中的指针
 一般只用于对象内部指针    
3.返回值为引用  和不为引用的区别   是否返回一个临时对象
 结论 如果要进行连续操作  比如++++++a 返回引用  a = b = c = d = e  返回引用
4.父类构造析构和子类的构造析构一样么??  不一样
 子类需要写自己的构造和析构
    子类调用构造函数的时候 需要先调用父类的构造及函数
    子类调用析构之后  调用父类的析构函数
 如果没有显性调用父类构造  会调用默认父类的构造函数
5.虚继承之后 只有一份拷贝  祖父类成员在孙子类成员中只有一份拷贝

猜你喜欢

转载自www.cnblogs.com/csu-lmw/p/9215342.html
今日推荐