C++知识点小结(三)

拷贝构造函数
  一种特殊的构造函数,就是用一个已有的对象去构造同类的副本对象,即对象克隆
  class 类名
  {
    类名(类名 &that)
    {
      ...
    }
  }
  编译器会默认生成一个拷贝构造函数
    编译器生成的拷贝构造函数默认会逐字节复制类中的每一个成员
    如果在类A中有类B的成员,会在类A的拷贝构造函数中自动调用类B的拷贝构造函数
  程序员可以自定义拷贝构造函数来取代默认的拷贝构造函数
    拷贝构造函数只能有一个,不能重载
    一旦自定义了拷贝构造函数,编译器就不再生成
    在自定义的拷贝构造函数中需要通过编写代码实现成员的复制
  一般情况下编译器生成的拷贝构造函数足以满足需求,不要轻易自定义拷贝构造函数
  使用拷贝构造的情况
    对象给对象赋值
    使用对象与函数传参
    将对象作为返回值
初始化列表
  一种成员的初始化方式
  class 类名
  {
    类名(参数列表):成员1(参数),成员2(参数)...
    {
      ...
    }
  }
  初始化列表可以解决构造函数的参数与成员重名的问题
  初始化列表会先于构造函数执行
  如果类成员是数组,可以用{}进行初始化
  如果有成员是类,可以在初始化列表中显示调用构造函数
  如果成员中有 const 成员或者引用成员,必须使用初始化列表
  类成员的构造顺序与初始化列表无关,而是与成员定义时的顺序有关
this 指针
  相同类型的对象各自拥有独立的成员实例,彼此共享成员函数
  为了让成员函数知道是哪个对象在调用,并准确访问到对象的成员,编译器会自动为每个成员函数添加一个看不到的参数,这个参数就是指向调用对象的 this 指针
  类中的所有成员都有 this 指针,包括构造、析构、拷贝构造等,只是构造中的 this 指向的是正在被创建的对象
  this 指针默认情况下都是隐藏的,在成员函数中访问成员变量时就自动补充了,但也可以显示使用
  使用 this 指针的情况
    区分成员变量与参数
    将对象作为返回值与其它对象作为交互
常对象与常函数
  创建对象时添加 const 关键字,这个对象就不可再修改,就有了常属性,就意味着整个对象中的所有东西都不能修改
  常对象不能调用普通成员函数,调用成员函数就相当于把对象的 this 指针传给了函数,会有被修改的风险
  定义函数时函数名前加 const 关键字,就成了常函数,常对象只能调用常函数,普通对象可以调用常函数
    常函数就相当于对 this 指针添加了 const 属性
  常函数与!常函数会形成重载不会冲突
  如果有成员确实需要修改值,却被 const 关键字修饰,可以对成员添加 mutable 关键字,此时即使是常对象调用常函数依然可以修改
析构函数
  当对象被销毁时自动调用的函数叫析构函数,对象的整个生命周期中只能被调用一次,它是对象被销毁前的最后一个执行动作
  class 类名
  {
    ~类名(void)
    {
      ...
    }
  }
  编译器会默认产生一个析构函数,默认析构函数负责销毁能看得到的成员,如果有成员是类,会自动调用成员的析构函数,成员的析构过程与构造过程相反
  析构函数虽然不能重载,但可以自定义,有自定义析构函数,默认析构函数就不会生成
  当类中有析构函数看不到的资源时(new/malloc),有需要还原的设置(把打开的文件关闭/把获取的数据保存),这时就需要自定义析构函数
赋值构造
  一个对象给另一个对象赋值的时候调用的函数
    Student stu2 = stu1;
    stu2 = stu1;
    void func(Student stu);
    fuc(stu1);
    Student func(void)
    {
      return *this;
    }
    Student stu = func();
  赋值构造函数的格式
    void operator = (Student &that)
    {
      ...
    }
    Student &operator = (Student &that)
    {
      ...
    }
    编译器会默认生成赋值构造,把对象A完全拷贝给对象B
    赋值构造和拷贝构造的区别
      拷贝构造 使用对象A去创建出对象B,调用时对象B还未生成
      赋值构造 对象A与B都已经构造完成,再将A的值赋值给B
      如果对象中有常成员,拷贝构造可以成功调用,但是赋值构造不行
    一般情况下默认的赋值构造是足以满足需求的,除非是有成员是指针,指向额外的内存空间
    自定义赋值构造
      确定赋值构造的格式
      防止自赋值
      分配新资源
      释放旧资源
      拷贝新内容
      代码利用(显式调用拷贝构造)
静态成员与静态函数
  类成员被 static 修饰,就会存储在bss段(此段有编译存放且大小固定),在程序中动态的创建对象时它的静态成员就无法创建,所有的类对象共享一个静态成员
  静态成员只能在类中声明,不能在类中定义(只能在类外定义)
    static 类型 类名::静态成员名;
    对象不能使用.或->访问静态成员,只能用类名::静态成员名进行访问
  静态成员就是声明在类中的全局变量,在任何位置都可以使用
    类名::静态成员名进行访问
  静态成员函数,类中的成员函数被 static 关键字修饰后就变成了静态成员函数,所有对象共享静态成员函数
  静态成员函数不会传递 this 指针,也就不能访问成员变量
    不通过对象也可以调用静态成员函数
      类名::静态成员函数(参数)
单例模式
  只能创建出一个对象的类,这种类就叫做单例类,这种模式就叫做单例模式
  单例模式的目的
    只允许存在唯一对象实例,提高安全性和稳定性
    商业应用
    网站计数器
    日志管理系统
    连接池
    线程池
    内存池
  获取对象实例的专门办法
    全局变量的定义不受控制
    专门办法是类的一部分
    借助类禁止在外部创建对象,仅在类内部提供获取对象的接口
  实现单例模式
    禁止在外部创建实例,私有所有的构造函数,private
    类自己维护其唯一实例
      静态成员变量 static 类名 instance;
      静态成员指针 static 类名 *instance;
    提供访问该实例的办法,静态成员函数getInstance()
  饿汉单例模式
    不管是否需要对象都已经创建好了
    优点 效率高、速度快、稳定
    缺点 浪费资源
  懒汉单例模式
    当首次使用获取对象时才会真正创建出对象
    优点 节约资源
    缺点 效率低、速度慢、不安全

猜你喜欢

转载自www.cnblogs.com/wannabeajoker/p/9489246.html
今日推荐