C++类的默认成员函数1 --- 构造函数

本文详细介绍了C++中的构造函数,包括其作用、如何初始化成员变量、构造函数的类型,以及在自定义类型成员中的应用。指出,即使没有显示定义构造函数,编译器也会生成默认构造函数,但自定义类型成员仍需调用它们的默认构造函数进行初始化。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构造函数

类当中有6个默认成员函数 不管我们有没有定义成员函数 都会有这6个默认的成员函数

  • 构造函数用来初始化
  • 析构函数用来清理
  • 拷贝函数是 使用同类对象初始化创建对象
  • 赋值重载主要是吧一个对象赋值给另一个对象
  • 取地址重载主要是普通对象和const对象取地址, 这两个默认函数很少会自己实现

1. 构造函数:

  • 作用 : 初始化对象的成员 (相当于这个空间已经有内容了, 构造函数是专门去初始化成员变量的)
  • 构造函数名与类名相同, 无返回值, 可以重载
  • 如果不显示定义构造函数, 编译器会自动生成一个默认的构造函数(默认构造的函数是无参的) 若是有显示定义的构造函数, 编译器就不会再去生成一个默认构造函数, 除非我们自己定义个无参构造函数

2. 构造函数的产生

  1. 要么不写, 编译器自己生成;
  2. 无参构造;
  3. 全缺省(所有的参数都被初始化了)
  • 全缺省的也算是默认构造函数, 但是默认函数只用存在一个, 一般会写全缺省的构造函数, 其有两个作用 ,一可以是默认构造 二还是带参构造,

  • 创建对象时, 编译器根据参数的个数自动调用对应参数个数的构造函数(有参的调有参的, 无参的调无参的) 编译器自动调用构造函数来初始化, 我们自己不能显式调用, 有了构造函数就不用再写设置函数

class Date{
public:
	// 下面这些就是构造函数 函数名和类名是相同的 且没有返回值 还可以重载 --> 构造函数是有多个的
	// 不需要我们亲自去调用, 创建对象的时候编译器亲自去调用
	Date(int year, int month, int day){
		this->_year = year;
		_month = month;
		_day = day;
	}
	// 这是全缺省的构造函数
	Date(int year = 1, int month = 1, int day = 1){
	//Date(int year, int month, int day){
		->_year = year;
		_month = month;
		_day = day;
		cout << "Date(int year = 1, int month = 1, int day = 1)" << endl;
	}

	// 这是构造函数的重载 这个供有一个参数的对象调用
	Date(int year){
		_year = year;
	}
	
	//重载的构造函数, 无参的为默认构造 只供无参对象调用 前面有了全缺省 这里就不需要写无参构造了
	//Date(){
	//	cout << "Date()" << endl;
//	}

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

void test(){
	// 如果我们不显示定义, 编辑器会默认生成无参构造函数
	Date d1, d2;  // 这行代码相当于是类的实例化 这两个对象的内容是空的 
	// 这里没有显式定义, 但是也调用了无参构造  这里的d1, d2为无参的对象
	d1.Display(); // 没有设置函数参数之前对象的内容是随机值
	d2.Display();

	d1.SetDate(2018, 5, 1);  // 这里才是对成员变量的初始化
	d2.SetDate(2018, 7, 1);
	
	// 相比上面的初始化 构造函数就更简单的了, 
	Date d1(2020, 5, 8); // 在运行到这里(实例化对象)时, 编译器会自动调用构造函数
	Date d2(2020, 5, 10);  // 这下就不用再去写设置函数(setData)了
	
	// 同时我们并不能显式的去调用构造函数 
	// d1.Date(2020, 5, 10);    是错的
	Date d3; // 这里会调无参构造, 成功创建取餐对象
	Date d3(); // 这个不是无参构造, 相当于是声明了一个函数. 
	//这个函数没有参数 返回值为Date 并没有实际指令 和调用


}
  • 调用无参构造时后面不能加(); 这个Data a(); 相当于是一个函数的声明

  • 若我们没有显示定义构造函数 则可以成功创建无参对象, 因为编译器会默认定义一个无参构造函数; 若我们显示定义了构造函数,编译器就不会再定义无参构造了, 而则这里就创建无参对象就会失败了, 因为没有无参构造函数供他调用; 若此时还需要创建无参对象 则就需要再次显示定义无参构造函数

  • 在已经显示定义了构造函数时, 要先创建无参对象, 前提必须自己再显式定义一个无参构造函数,

  • 没有实际的指令 如果类中有自定义成员, 当前对象会去自动调用自定义成员的默认构造函数 完成对自定义成员的初始化

3. 自定义类型成员的调用默认构造函数

关于编译器生成的默认成员函数,大家会有疑惑:在我们不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又没什么用?d对象调用了编译器生成的默认构造函数,但是d对象year/month/_day,依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么卵用??

  • 解答:C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语法已经定义好的类型:如int/char…; 而自定义类型就是我们使用class/struct/union自己定义的类型,看看下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员函数
class E{
public:

	//如果有自定义成员,当前类的构造函数会自动调用自定义成员的默认构造函数,完成自定义成员的初始化
	E(){
	} 
	E(int a){
	}
	// 这两个都是有错的,  调不动E的默认构造函数
	// 如果上述 Date 类 中不存在 Date 的默认构造, 就会造成编译错误
private:
	Date _d; // 会去调用Date的默认构造函数,完成成员的初始化, 
};

void test2(){
	E e;  //编译器会自动生成一个无参的默认构造
	E e2(2);// 调带参构造
}
  • 测试 test2 中, 对象e会先进入E中调用无参构造函数, 然后再去Date类中调用Date的默认构造函数 完成自定义成员Date _d的初始化 , 然后再返回到E中结束无参构造函数的调用; 对象e2会先进入E中调用带参构造, 然后进入Date类中调用Date的带参构造,完成自定义成员的初始化, 然后再返回到E中结束带参构造的调用.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值