构造函数、拷贝构造函数、析构函数

构造函数、拷贝构造函数、析构函数

构造函数

一、概念
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编译器自动调用,在对象的生命周期内只调用一次且是在创建对象时被调用的,它保证了每个成员都有一个合适的初始值。
//代码

//构造函数
class Date
{
public:
    Date(int year, int month, int day)
    {
        _year = year;
        _month = month;
        _day = day;
    }//构造函数
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d(2018, 4, 10); //对象d是在调用完构造函数后,才被创建好的
    return 0;
}

二、特性

  • 函数名与类名相同。
  • 没有返回值。
  • 新对象被创建时,由编译器自动调用,且在对象的生命周期内仅调用一次。
  • 构造函数可以重载,实参决定了调用哪个构造函数。
  • 无参构造函数和带有缺省值的构造函数都认为是缺省的构造函数,并且缺省的构造函数只能有一个,否则会造成调用不明确。
  • 有初始化列表(一般不用)
//带有初始化列表的构造函数
class Date
{
public:
    //带有初始化列表的构造函数
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
    {}
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d(2018, 4, 10);
    return 0;
}
  • 如果没有显式定义时,编译器会合成一个默认的构造函数。
  • 构造函数不能用const修饰。因为在构造函数中可能会对成员对象赋值,若被const修饰之后,就不能进行赋值操作。
  • 构造函数不能为虚函数。

三、对象初始化

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每一个成员变量后面跟一个放在括号中的初始值或表达式。
注:
(1)每个成员在初始化列表中只能出现一次,因为成员被初始化时,只能被初始化一次。
(2)初始化列表仅用于初始化类的数据成员,并不指定这些数据成员的初始化顺序,数据成员在类中声明顺序就是参数列表中的初始化顺序。
(3)尽量避免使用成员初始化成员,成员的初始化顺序最好和成员的定义顺序保持一致。

四、构造函数的作用

  1. 构造对象
  2. 初始化对象

注:

- 类中一定要放在初始化列表位置进行初始化的成员:
引用成员变量、const修饰的成员变量、类类型成员(该类有非缺省的构造函数)

拷贝构造函数

一、概念

只有单个行参,而且该形参是对本类型对象的引用(常用const修饰),这样的构造函数成为拷贝构造函数。创建对象时使用已存在的同类对象来进行初始化,由编译器自动调用。

//拷贝构造函数
class Date
{
public:
    //构造函数
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
    {}
    //带有初始化列表的拷贝构造函数
    Date(const Date& d) //加const是为了避免对实参造成不必要的改动
        : _year(d._year)
        , _month(d._month)
        , _day(d._day)
    {}
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1(2018, 4, 14);
    Date d2(d1);
    return 0;
}

二、特征
1. 构造函数的性质拷贝构造函数都满足。
2. 参数必须使用类类型对象引用传递,如果进行传值的话会使程序陷入死循环。
3. 如果没有显式定义,系统会自动合成一个默认的拷贝构造函数。默认的拷贝构造函数会依次拷贝类的数据成员完成初始化。但有些类的拷贝构造函数必须显示的定义出来,否则会造成程序崩溃。

三、使用场景

  1. 对象实例化对象。Date d2(d1);
  2. 作为函数的参数。Date Test(const Date d);

析构函数

一、概念
与构造函数功能相反,在对象被销毁时,由编译器自动调用,完成类的一些资源清理和汕尾工作。

//析构函数
class Date
{
public:
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
    {}
    ~Date()
    {}
private:
    int _year;
    int _month;
    int _day;
};
int main()
{
    Date d1(2018, 4, 19);

    return 0;
}

二、性质

  • 析构函数在类名前加~
  • 析构函数无参数无返回值,所以析构函数不能函数重载。
  • 一个类有且只有一个析构函数。若没有显式定义时,系统会根据情况自动生成缺省的构造函数(当类B中包含类A的类的成员对象,且类A中有析构函数而类B无时,编译器会自动合成析构函数)。
class Time
{
public:
    Time(int hour, int minute, int second)
        : _hour(hour)
        , _minute(minute)
        , _second(second)
    {}
    ~Time()
    {}
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
public:
    Date(int year, int month, int day)
        : _year(year)
        , _month(month)
        , _day(day)
        , t()
    {}
private:
    int _year;
    int _month;
    int _day;
    Time t;
};
int main()
{
    Time t(11, 4, 20);
    Date d(2018,4, 20, t);
    return 0;
}
  • 对象生命周期结束时,C++编译系统自动调用析构函数。
  • 注意析构函数内部并不是删除对象,而是做一些清理工作。

猜你喜欢

转载自blog.csdn.net/bit666888/article/details/81177911
今日推荐