您的位置:首页 > 编程语言 > C语言/C++

详叙C++的构造函数,默认构造函数与析构函数

2017-02-15 19:29 204 查看
//声明一个Data类

class Data

{

public:
Data(int _year, int _month, int _day) ://构造函数
year(_year),
month(_month),
day(_day){}
Data(const Data&d)//拷贝构造函数
{
year = d.year;
month = d.month;
day = d.day;
}
Data(const Data&d) = delete;//阻止拷贝
/*data(int y=10, int m=10, int d=10);在声明构造函数时指定默认参数值
构造函数中参数的值既可以通过实参传递,也可以指定为某些默认值,
如果用户不指定实参值,编译系统就使形参取默认值
注意:应在声明函数时指定默认值,而不能只在定义构造函数时指定默认值*/
~Data(){}//析构函数

private:
int year;
int month;
int day;

};

/*
构造函数:

1.定义:是一个特殊的成员函数,对对象进行初始化,构造函数名字必须与类名同名,无类型,无返回值,

不需要用户调用,也不能被用户调用,在建立对象时自动执行,在对象的生命周期内只调用一次

2.可以在声明构造函数时指定默认参数

例如:data(int y=10, int m=10, int d=10);

//如果用户不指定实参值,编译系统就使形参取默认值

注意:应在声明函数时指定默认值,而不能只在定义构造函数时指定默认值

3.初始化:

1)初始化列表用于初始化数据成员,并不指定这些数据成员的初始化顺序,

数据在类中定义顺序就是在参数列表中初始顺序。

2)尽量避免使用成员初始化成员,成员的初始化顺序最好和成员定义的顺序保持一致

4.特性:

1)函数名与类名相同

2)没有返回值

3)有初始化列表(可以不用)

4)新对象被创建,由编译器自动调用,且在对象的生命周期内只调用一次。

5)构造函数可以重载,实参决定了调用哪一个构造函数

6)无参的构造函数和带有缺省值(缺省值不能随便给,缺省值的个数可以是任意的,

但是应从右向左给定)的构造函数都认为是缺省构造函数,并且缺省构造函数只能有一个。

7)如果没有显示定义时,编译器会提供一个默认构造函数(不一定,看程序是否需要构造函数,

详细解释见上篇博客“c++合成默认构造函数的真相”)。

5.作用:构建对象,初始化对象,类型转换
拷贝构造函数:

1.定义:只有单个形参,而且该形参必须是本类对象的const引用(请思考为什么?),它是特殊的构造函数

创建对象时使用已经存在的同类对象来进行初始化,由编译器自动调用。

2.特征:

1)它是构造函数的重载

2)如果没有显式定义,系统会自动合成一个默认的拷贝构造函数,默认的构造函数

会将其参数的成员逐个拷贝到正在创建的对象中。

3)用途:

a.对象实例化对象

例如:

data d1(2016,2,14);

data d2(d1);

b.将一个对象作为实参传递非引用类型的形参

例如:

void fun(const data d2){}

c.从一个返回类型为非引用类型的函数返回一个对象

data fun1()

{

   data d3;

   return d3;

}

解答:为什么拷贝构造函数形参必须是本类对象的const引用?

若定义为:Data(const Data d)

因为参数的传递本身就是复制,而复制一个临时的Data对象的时候要调用拷贝构造函数。

(也就是自己,调用自己的时候又是一次参数传递,所以又要调用一次自己(即:

调构造函数)),这样会一直恶性循环下去,造成无休止递归调用。

4.阻止拷贝:

在新标准下,我们可以将拷贝构造函数和拷贝赋值运算符定义为删除的函数

(delete)来阻止拷贝,虽然我们声明了删除的函数,但是不能以任何方式

使用它们,格式为:在参数列表后面加上“=delete”来指出我们希望将它定

义为删除的。

例如:

Data(const Data&d) = delete;//阻止拷贝

data &operator=(const data&)=delete//阻止赋值

注意:=delete必须出现在第一次声明的地方,我们可以对任何函数指定=delete,

虽然删除函数主要作用是禁止拷贝控制成员,但当我们希望引导函数匹配过程时,

删除函数有时也是有用的。

析构函数:

1.定义:是类的一个成员函数,与构造函数功能相反,

在对象被销毁时,编译器自动调用,释放对象使用的资源(不是删除对象),并销

毁对象的非static数据成员(static局部对象在函数调用结束时对象并不释放,因此

也不用调用析构函数,只有在main函数结束或调用exit函数结束程序时候,才调用static

局部对象的析构函数)。

2.先构造的后析构,后构造的先析构(他相当于一个栈,先进后出)。

3.析构函数没有返回值,没有函数类型,也没有函数参数。因此,它不能被重载,

一个类可以有多个构造函数,但只有一个析构函数。

*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: