【C++】类的默认构造函数

  • Post author:
  • Post category:其他




类的默认成员函数



1. 构造函数

初始化类

  • 函数名与类名

    相同
  • 无返回值
  • 对象实例化时

    编译器自动调用对应的构造函数
  • 构造函数可以

    重载

我们测试一下对象实例化时

编译器自动调用对应的构造函数

#include <iostream>
using namespace std;

class Date
{
public:
    //含参的构造函数
	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;

	}

	void print()
	{
		cout << _year << "-" << _month  << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;//对象实例化
	d1.print();

	return 0;
}

image-20220121230708377


测试一下构造函数可以

重载

class Date
{
public:

	Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}

	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;

	}

	void print()
	{
		cout << _year << "-" << _month  << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d1;//这里使用的时候存在歧义
	Date d2(2022,1,21);

	return 0;
}

image-20220124141946657

可以构成重载,但能否使用另外说明

可以改成

Date()
{
	_year = 0;
	_month = 0;
	_day = 0;
}

Date(int year, int month, int day)
{
	_year = year;
	_month = month;
	_day = day;

}

//上面两个函数其实等价于下面一个函数

Date(int year = 0, int month = 0, int day = 0)
{
	_year = year;
	_month = month;
	_day = day;

}



2. 默认构造函数

如果我们自己没有写构造函数,类会自己生成一个构造函数初始化

image-20220124152018474

但数据显示根本没有给我初始化0

原因:C++中类分为两个内置类型(基本类型),自定义类型

  • 内置类型:

    int char double

    指针 数组等
  • 自定义类型:

    struct class

    定义的类型

如果我们不写构造函数,编译器默认生成构造函数,并且

对内置类型不作初始化处理

,而对自定义类型,会去寻找

自定义类型的默认构造函数(没有参数就可以访问的构造函数),如果没有则会报错

image-20220124171942273


有默认构造函数时,没有错误,无默认构造函数时,(全缺省可以)半缺省以及要传参数会出错

所以有三种:

不会报错的

  • 全缺省
  • 无参
  • 不写(程序自动生成,但是无用默认构造函数(什么都不做))

  • 但默认构造函数,有且只能有一个
  • image-20220126163231333


歧义:

image-20220126162930236


可能你想不传参定义对象,但这里对象创建的时

d1()


例子:在类里面定义一个自定义类型的

成员变量st

当我们一步一步调试的时候,

在初始化类里面内置类型之前,先初始化了自定义类型的成员变量st

#include <iostream>
using namespace std;

class st
{
public:
	st()
	{
		a = 0;
		b = 0;
	}
private:

	int a;
	int b;
};

class Date
{
public:

	Date(int year = 0, int month = 0, int day = 0)
	{
		_year = year;
		_month = month;
		_day = day;

	}

	void print()
	{
		cout << _year << "-" << _month  << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
	st ST;
};

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



3. 析构函数

对象在销毁时会自动调用析构函数

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

  • 无参数无返回值

  • 一个类有且只有一个析构函数

    。若未显式定义,系统会自动生成默认的析构函数。 (因为没有参数,所以不构成函数重载)

  • 对象生命周期结束时

    ,C++编译系统系统自动调用析构函数。比如

    return 0

    的时候,看的是定义

用栈去解释

class Stack
{
public:
    //初始化栈
	Stack(int capacity = 4)
	{
		_a = (int*)malloc(sizeof(int) * capacity);

		if (_a = nullptr)
		{
			cout << "malloc fail" << endl;
			exit(-1);
		}
		_capacity = capacity;
		_top = 0;
	}
    //销毁栈
	~Stack()
	{
		free(_a);
		_a = nullptr;
		_capacity = 0;
		_top = 0;
	}
private:
	int* _a;//数组,动态栈
	int _top;//栈顶
	int _capacity;//栈大小
};

int main()
{
	Stack d1;
    Stack d2;
	return 0;
}

  • 因为是栈,后进先出,

    初始化顺序先d1后d2,销毁顺序先d2,后d1

再利用上面年月日的例子

class Date
{
public:
	Date(int year = 1, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;

	}

	~Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
};

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

可以在运行的时候发现,



Date d1;

走完之后,年月日都为

1

(构造函数)





return 0;

之前,年月日变为0

,将析构函数删除后,不会变为

0

,编译器并没有像析构函数那样帮我们销毁(重新初始化)

image-20220129181703677

可见析构函数跟构造函数一样,不写的话,默认构造函数/析构函数不会起什么作用,同样是内置类型不作处理,自定义类型需要调用对应的析构函数。



关于为什么C++不作处理

像指针

int* a;//普通指针
FILE* x;//文件指针

如果free掉文件指针会出大问题,有些是不需要它free的,所以对内置类型不作处理,对自定义类型需要默认的析构函数




4. 拷贝/复制构造函数

  • 首先

    它和类名相同,没有返回值

    ,这就意味着它跟构造函数构成函数重载

  • 参数只有一个,并且是引用传参

    ,否则会造成无限拷贝构造(传值需要拷贝)

  • 传引用不需要调用拷贝构造
Date(const Date& d)
{
	_year = d._year;
	_day = d._day;
	_month = d._month;
}

  • 对于内置类型,按字节拷贝(浅拷贝)
  • 如果成员有是数组指针,
Stack st1;
// 拷贝复制
Stack st2(st1);
  • 这里

    st2

    拷贝了

    st1

    的指针,当修改其数组中元素时,

    st1

    也会被修改,我们需要的是独立的类
  • 如果内置类型是指针,如果是动态开辟的指针,不能被

    free

    两次
  • 但如果自己不写

    free

    ,默认的析构函数不会去

    free

    动态开辟的指针
  • 自定义类型调用自己的拷贝构造



版权声明:本文为qq_53656490原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。