【C++】构造函数详解

在这里插入图片描述


个人主页 :阿然成长日记 点击可跳转
个人专栏: 数据结构与算法C语言进阶
不能则学,不知则问,耻于问人,决无长进

文章目录

  • 前言:
  • 一、 什么是构造函数
  • 二、构造函数的特征特征
  • 三、构造函数类型
    • 1.无参构造
    • 2.带参构造函数
    • 3.全缺省构造函数(后面有补充)
      • (1)传入前一个,前两个,全传入。
      • (2)传入0个参数时
  • 四、默认构造函数意义:
    • 1.问题引入:
    • 2.内置类型和自定义类型
  • 五、补充
  • 后续补充!

前言:

使用类实例化对象时,每一个对象都要进行初始化,都要进行调用初始化函数,这个操作是实例化对象的必要操作,那么有没有更好的方式来简化这个调用操作。于是C++便推出了构造函数

一、 什么是构造函数

构造函数是特殊的成员函数,构造函数千万不要认为它是用来创建对象的,其实构造函数的主要任务并不是开空间创建对象,而是初始化对象。

  • 没有构造函数,需要自己手动写初始化函数,如下:
class Data
{
public:
	void Init(int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print(){}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.Init(1999, 1, 1);
	d1.print();
	Data d2;
	d2.Init(2023, 1, 1);
	d2.print();
	return 0;
}
  • 使用构造函数
class DData
{
public:
	DData(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	DData d1(2023, 11, 14);
	d1.print();
	return 0;
}

二、构造函数的特征特征

  1. 函数名类名相同。
  2. 返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载
    【C++】构造函数详解_第1张图片
    如上代码,两个Data构造函数,构成重载,但是不能同时存在,无参调用时会造成歧义(不知道调哪一个)。所以,在写构造函数时使用全缺省方式,更加合适。

三、构造函数类型

1.无参构造

格式:系统默认生成

class Data
{
public:
//这里不写构造函数

private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	return 0;
}

2.带参构造函数

格式 Data(int year, int month, int day);

class DData
{
public:
//构造函数
	Data(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(2023, 11, 14);
	d1.print();
	return 0;
}

3.全缺省构造函数(后面有补充)

使用全缺省构造函数,它的特殊之处在于带有初始值。如果传参时没有覆盖,那么就会将自带的初始值赋给变量。

(1)传入前一个,前两个,全传入。

如下代码,我们只传入前两个参数或者只传入前一个参数又或是全传入。

Data d1(19996); 或者 Data d1(1999);或者Data d1(199966)
class DData
{
public:
//构造函数
	Data(int year=1, int month=1, int day=1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void print() 
	{
		cout << "时间:" << _year << _month << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1(19996);
	d1.print();
	return 0;
}

【C++】构造函数详解_第2张图片

(2)传入0个参数时

当传入0个参数时,应该怎么写,会不会和无参构造冲突?

其实当传入0个参数时,我们应该写成Data d1;而不能写成Data d1();的形式。写法与调用无参构造写法一样,但是,默认的无参构造函数不会进行初始化,而全缺省构造函数对其进行了初始化。
如下:
【C++】构造函数详解_第3张图片

注意:

  • 不能写成Data d1();否则就成了函数声明
  • 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。

四、默认构造函数意义:

默认构造的三种形式:
【C++】构造函数详解_第4张图片
总结:可以不传参数调用的都叫默认构造

1.问题引入:

执行下面代码:

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Data d1;
	d1.print();
	return 0;
}

【C++】构造函数详解_第5张图片
可以发现,使用默认构造,变量都是随机值,并没有任何处理,这样说默认构造好像没有什么用啊!想要弄清楚这个问题,我们通过下面的学习。

2.内置类型和自定义类型

默认生成的构造函数对于:

  • 内置类型(如int,double,指针等系统定义的类型): 不做处理
  • 自定义类型(自己定义的类型,如自己定义的):会对其进行处理,会调用自定义类型的类中的构造函数,如果没有 ,那么也还是随机值。

如:定义了一个栈类,使用两个栈实现队列,这个队列中的数据类型有Stack类型的,当调用默认构造时,Stack类型的变量会去栈类中调用构造函数,为其赋初值。有点绕,但是写一份代码太麻烦了。(仅供自己理解)

五、补充

其实这种定义并不方便,更好的做法是,int就默认赋值0,double就默认赋值0.0等等。
所以在C++11中做出了补丁,也就是允许在类在声明变量时给缺省值。

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year =1;
	int _month =1;
	int _day =1;
};

变动的地方也就在这里:如下
【C++】构造函数详解_第6张图片
我们前面说过,类中的成员变量都是声明,那么我们现在这样写是不是就是定义了呢?答案是它还是声明,并不是定义,没有开空间。

使用这种写法,我们在以后的声明中可以直接不写构造函数,让编译器默认自己生成构造函数。
例如:

class Data
{
public:
	void print() 
	{
		cout << "时间  " << _year <<"+" << _month << "+" << _day << endl;
	}
private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

int main()
{
	Data d1;
	d1.print();
	return 0;
}

【C++】构造函数详解_第7张图片

总结:内置类型赋予了缺省值,或者成员变量都是自定义类型,可以直接使用默认的无参构造。

后续补充!

你可能感兴趣的:(C++基础,c++)