c++中类的默认四个成员函数介绍(构造函数+拷贝构造+析构函数+赋值运算符重载函数)

在C++中,类的6个默认的成员函数包括:

构造函数、析构函数、拷贝构造函数、赋值运算符重载函数、取地址操作符重载、const修饰的取地址操作符重载。

本文将主要介绍前四个成员函数:

一、构造函数

在c++程序中,对象的初始化时一个不可缺少且十分重要的问题,因此c++在类的设计中提供了构造函数。
构造函数,顾名思义,为对象分配空间,进行初始化,它是一种特殊的成员函数,具有以下特点:

  • 1.函数名与类名相同。
  • 2.无返回值。
  • 3.构造对象的时候系统会自动调用构造函数。
  • 4.可以重载。
  • 5.可以在类中定义,也可以在类外定义。
  • 6.如果类中没有给出构造函数,编译器会自动产生一个缺省的构造函数,如果类中有构造函数,编译器就不会产生缺省构造函数。
  • 7.全缺省的构造函数和无参的构造函数只能有一个,否则调用的时候就会产生冲突。
  • 8.没有this指针。因为构造函数才是创建对象的,没有创建对象就不会有对象的首地址。

构造函数,说来就是给成员变量进行初始化。而初始化却有两种方法:初始化列表、构造函数函数体内赋值。

举例:以日期类来说明:

class Date 
{
public:
    Date()//无参构造函数
    {
        m_year = 2016;
        m_month = 7;
        m_day = 6;
    }
    Date(int year = 1900, int month = 1, int day = 1)//全缺省的构造函数
    {
        m_year = year;
        m_month = month;
        m_day = day;
    }
    Date(int year, int month, int day) :m_year(year), m_month(month), m_day(day)
        //初始化列表初始化成员变量
    {
    }
    void print()
    {
        cout << m_year << "-" << m_month << "-" << m_day << endl;
    }
private:
    int m_year;
    int m_month;
    int m_day;
};
int main()
{
    Date date(2017,6,28);
    date.print();
    system("pause");
    return 0;
}

上边这段代码只是为了解释初始化列表初始化成员变量和在构造函数体内初始化,也解释了无参构造函数和全缺省的构造函数。声明:由于上边的代码同时给出无参和全缺省的构造函数,产生调用冲突,编译不通过。

既然有两种初始化的方法,我们究竟该怎样选择呢??

尽量使用初始化列表,因为它更高效。

有些成员变量必须再初始化列表中初始化,比如:

  • 1、常量成员变量。(常量创建时必须初始化,因为对于一个常量,我们给它赋值,是不对的)

  • 2、引用类型成员变量。(引用创建时必须初始化)

  • 3、没有缺省构造函数的类成员变量。(如果构造函数的参数列表中有一个类的对象,并且该对象的类里没有缺省参数的构造函数时,要是不使用初始化列表,参数中会调用无参或者全缺省的构造函数,而那个类中又没有。)

二、析构函数

析构函数是一种特殊的成员函数,具有以下特点:

  • 析构函数函数名是在类名加上字符~。

  • 无参数无返回值(但有this指针)。

  • 一个类有且只有一个析构函数,所以肯定不能重载。若未显示定义,系统会自动生成缺省的析构函数。

  • 对象生命周期结束时,C++编译系统系统自动调用析构函数。

  • 注意析构函数体内并不是删除对象,而是做一些清理工作。(比如我们在构造函数中动态开辟过一段空间,函数结束后需要释放,而系统自动生成的析构函数才不管内存释放呢,所以需要人为地写出析构函数)

注意:对象生命周期结束后,后构造的对象先释放。

三、拷贝构造函数

用已有的对象创建一个新的对象。仍然使用上边的日期类举例:

int main()
{
       Date d1(2016,7,6);
       Date d2(d1);
       system("pause");
       return 0;
}

上边是用d1创建一个d2,系统会给出默认的拷贝构造函数,并且该函数的参数是一个常引用,我们想象为什么必须是引用呢,如果不是又会发生什么。

如果不是引用,形参是实参的一份临时拷贝,由于两者都是对象,此时就会调用自己的拷贝构造函数,陷入无限递归中…….

调用拷贝构造函数的3种情况:

  • 当用类的一个对象去初始化该类的另一个对象时。

  • 当函数的形参是类的对象,调用函数时进行形参和实参的结合时。

  • 当函数的返回值是对象,函数执行完返回调用者时。(函数运行结束后,返回的对象会复制到一个无名对象中,然后返回的对象会消失,当调用语句执行完之后,无名对象就消失了)

调用拷贝构造函数的两种方法:

1.代入法:Person p2(p1);

2.赋值法:Person p2 = p1;

四、赋值运算符重载函数

它是两个已有对象一个给另一个赋值的过程。它不同于拷贝构造函数,拷贝构造函数是用已有对象给新生成的对象赋初值的过程。

默认的赋值运算符重载函数实现的数据成员的逐一赋值的方法是一种浅层拷贝。

你可能感兴趣的:(c)