C++学习笔记——(三)类的初始化、复制、析构

1、类的初显示初始化

  • 方法
    • 在创建对象时,显示指定各个成员的值
    •  类似于用在初始化数组上的初始化表
  • 缺点
    • 只能被应用在所有数据成员都是公有的类的对象上
    • 它要求程序员的显式干涉 增加了意外和错误的可能性

 

2、构造函数

  • 概述
    • 构造函数与类同名,我们以此来标识构造函数
    • 构造函数上惟一的语法限制是,它不能指定返回类型,甚至 void 也不行
    • C++语言对于一个类可以声明多少个构造函数没有限制,只要每个构造函数的参数表是惟一的即可
  • 使用方法
    • C++要求,在类对象首次被使用之前,构造函数将被应用在该对象上
    • 编译器会重写我们的程序,在类对象首次被使用之前,插入对构造函数的调用
      • 如果构造函数实例被定义为 inline,那么它就会在调用点上被展开
    • 为构造函数指定实参有三种等价形式

      Account acct1( "Anna Press" );

      Account acct2 = Account( "Anna Press" );

      Account acct3 = "Anna Press";

  • acct3 的形式只能被用于指定单个实参的情形
  • 对于两个以上的实参,只能使用 acct1 和 acct2 的形式
  • 用缺省构造函数初始化类对象的正确声明是去掉尾部的小括号

      Account newAccount;

  • 类的初始化有一种可替换的语法:成员初始化表(member initialization list)
    • § 是由逗号分开的成员名及其初值的列表

      Account() :

        _name( 0 ),  _balance( 0.0 ), _acct_nmbr( 0 ) {}

  •  成员初始化表只能在构造函数定义中被指定,而不是在其声明中
  • 注意点
    • 构造函数不能用 const 或 volatile 关键字来声明
    • 这并不意味着 const 和 volatile 类对象不能用构造函数来初始化
    • 而是说,被应用到 类对象上的适当的构造函数与该对象是 const 非 const 或 volatile 无关
    • 只有当构造函数执行完毕,类对象已经被初始化的时候,该类对象的常量性才被建立起来
    • 一旦析构函数被调用,常量性就消失了
    • 因此,一个 const 类对象在“从其构造函数完成到析构函数开始”这段时间内,才被认为是 const 的,对 volatile 类对象也一样
  • 缺省构造函数——隐式初始化
    •  缺省构造函数是指不需要用户指定实参就能够被调用的构造函数
    • 这并不意味着它不能接受实参,只意味着构造函数的每个参数都有一个缺省值与之关联
    • 案例
      •   当我们写
        • int main()

            {  Account acct;

              // ...

            }

  • 编译器首先检查 Account 类是否定义了缺省构造函数,以下情况之一会发生
    • 定义了缺省构造函数,它被应用到 acct 上
    • 定义了缺省构造函数,但它不是公有的,acct 的定义被标记为编译时刻错误,main() 没有访问权限
    • 没有定义缺省构造函数,但是定义了一个或者多个要求实参的构造函数,acct 的定义被标记为编译时刻错误,实参太少
    • 没有定义缺省构造函数,也没有定义其他构造函数,该定义是合法的,acct 没有被初始化,没有调用任何构造函数

 

3、拷贝构造函数

  • 概述
    • 默认情况下,一个类对象向该类的另一个对象作拷贝是通过依次拷贝每个非静态数据成员来实现的
    • 类的设计者也可以通过提供特殊的拷贝构造函数(copy constructor)来改变缺省的行为
    • 如果定义了拷贝构造函数,则在用一个类对象初始化该类另一个对象时,它就会被调用
  • 原理
    • 拷贝构造函数有一个指向类对象的引用作为形式参数

 

4、析构函数

  • 概述
    • 提供构造函数是为了自动获取资源
    • 析构函数则是构造函数的对称操作,它为生命期即将结束的类对象返还相关的资源或者自动释放资源
    • 析构函数是构造函数的互补
  • 原理
    • 当一个类对象离开了它的作用域,或者delete表达式应用到一个类对象的指针上时,析构函数会被自动调用
    •  析构函数主要被用来放弃在类对象的构造函数或生命期中获得的资源,如释放互斥锁,或删除由操作符 new 分配的内存
  • 使用
    • 析构函数的名字是在类名前加上波浪线 ~
    • 析构函数不返回任何值,也没有任何参数
    • 因为析构函数它不能指定任何参数,所以它也不能被重载
    • 对于一个类,我们只能提供一个析构函数,他被应用在类的所有对象上
    • 一般地,如果一个类的数据成员是按值存储的,则无需析构函数,这些成员的存储区在每个类对象生命期的开始和结束时,会由编译器自动分配和释放
    • 并不是每一个类都要求有析构函数,即使我们为该类定义了一个或多个构造函数
原文地址:https://www.cnblogs.com/snailt/p/13558640.html