C++中所有的构造函数

构造函数的作用:当创建对象时,系统分配了内存空间后,会自动调用相应的构造函数。

  • 默认构造函数没有参数,如果创建一个类,没有定义任何的构造函数,系统会自动生成默认的构造函数。

  • 一般构造函数含有参数的构造函数,一个类可以含有若干个一般构造函数,前提是构造函数之间的参数数量或类型不同。

  • 拷贝构造函数参数为该类的常量引用对象,如果类中没有定义拷贝构造函数,系统会默认生成一个拷贝构造函数,但是是浅拷贝

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
        // 重载拷贝构造函数,重载后的拷贝构造函数支持深拷贝
    ClassA(ClassA &obj)
    {
    // 拷贝 stack 域的值
    m_nId = obj.m_nId;
    // 新建 heap 空间
    m_pszName = new char[strlen(obj.m_pszName) + 1];
    // 拷贝 heap 空间的内容
    if (m_pszName != NULL)
    {
    strcpy(m_pszName, obj.m_pszName);
    }
    }

    private:
    int m_nId;
    char* m_pszName;

  • 赋值构造函数:其实并非是构造函数,而是“重载赋值操作符的函数”。该函数的参数为该类的常量引用对象返回值该类的引用类型。==(有返回值,前三者无返回值)==

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    // 重载赋值运算符
    ClassA& operaton=(const ClassA& obj)
    {
    // 适应自赋值(obj = obj)操作
    if (this == &obj)
    {
    return *this;
    }

    // 新建 heap 空间
    int iLength = strlen(str.m_pData);
    char* pTemp = new char[iLength + 1];

    // 新建 heap 空间成功后,再释放掉已有的 heap 空间
    // 保证异常安全性
    if (m_pszName != NULL)
    {
    delete []m_pszName;
    m_pszName = NULL;
    }

    m_pszName = pTemp;
    // 拷贝 heap 空间的内容
    strcpy(m_pszName, obj.m_pszName);

    // 拷贝 stack 域的值
    m_nId = obj.m_nId;

    return *this;
    }
    private:
    int m_nId;
    char* m_pszName;
  • 移动构造函数无返回值类型,参数为右值引用的对象类型

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ClassName(ClassName&& t)
    {
    if(t.m_pazName == nullptr)
    {
    this->m_pszName=t.m_pszName; // 进行转移并非f
    t.m_pszName=nullptr;
    this->m_nID=t.m_nID;
    }
    }

    private:
    int m_nID;
    char* m_pszName;

拷贝构造函数&赋值构造函数区别:

  • 函数定义上:拷贝构造函数没有返回值,参数为该类的常量引用类型;赋值构造函数返回值为该类的引用类型,参数为该类的常量引用。
  • 函数实现上:由于赋值构造函数是在源和目标对象都已经创建的情况下进行深拷贝,因此需要先释放原有的heap区资源;而拷贝构造函数是在对象创建时调用,因此无需释放原有的heap区内存,直接申请heap区资源进行拷贝即可。