C++类の默认成员函数

        在C++中定义一个类,哪怕类中什么都没定义,是一个空类,编译器仍然会生成以下六个默认的成员函数:构造函数、拷贝构造函数、析构函数、赋值运算符重载、取地址运算符重载和const取地址运算符重载。一般来说,前四个自己实现较多,后两个使用编译器默认生成的即可。(注:并不是说一定会自动生成,如果生成的成员函数没有任何意义,就不会生成)。

        从功能上来说,构造函数负责完成对象的初始化工作,析构函数与之相对应,负责完成对象资源的清理工作,拷贝构造函数用于同类对象初始化创建对象,赋值重载用于把一个对象赋值给另一个对象。

        构造函数:       

构造函数是特殊的成员函数,名字和类名相同,创建一个类的类型对象时由系统自动调用,给对象中的每个数据成员赋一个合适的初值,并且在对象的生命周期内只调用一次。 构造函数的任务并不是为了给对象创建空间,而是为了初始化对象,给对象赋一个合理的初值,如果自己显式定义了构造函数,系统将不再自动生成。

特点:名字与类名相同、没有返回值、创建对象时由编译器自动调用、构造函数可以重载

默认构造函数:无参的默认函数和全缺省构造函数以及编译器自动生成的构造函数统称为默认构造函数,默认构造函数只能有一个

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)//全缺省
	{
		_year = year;
		_month = month;
		_day = day;
	}
	~Date()//这个析构函数好像没啥用
	{}
private:
	int _year;
	int _month;
	int _day;
};

        析构函数:

  名字:~ + 类名,其特点是无参数、无返回值

一个类有且只有一个析构函数,析构函数不能重载, 和构造函数功能相反,构造函数时完成对象的初始化,析构函数是完成对象的回收工作,但不是销毁对象,局部变量在生命周期结束时是由编译器完成空间回收的,析构函数是完成类的一些其他资源的回收工作的,例如动态开辟内存的回收。

一般来说,像上面的日期类这种没有涉及到内存管理这种需要回收资源的,编译器自动生成的默认成员函数是够用的,一旦涉及到了资源的回收,那么这些默认成员函数都需要自己显式定义。

class String
{
public:
	String(const char* str = "Rainbow")
	{
		_str = (char*)malloc(strlen(str) + 1);
		strcpy(_str, str);
	}
	~String()
	{
		free(_str);//析构函数用于释放资源
	}
private:
	char* _str;
};

拷贝构造函数:

        拷贝构造函数是构造函数的重载,其参数只有一个且只能为该类定义的对象的引用,必须使用引用传参,使用传值方式则会引发无穷递归。如果没有涉及到资源管理(动态开辟,内存手动回收),赋值操作是否显式提供都可以,编译器生成的默认拷贝构造函数会完成如果类中涉及到了资源管理,用户自己必须显式实现拷贝构造函数,否则按照编译生成的默认拷贝构造函数的浅拷贝的方式完成,会造成两个问题:

1、内存泄漏

2、多个对象共享同一份资源,多个对象销毁时对同一份资源多次释放引发程序崩溃

class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	~Date()
	{}
	Date(const Date& d)//拷贝构造函数,参数为类类型的引用
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
private:
	int _year;
	int _month;
	int _day;
};

运算符重载:

        对于自定义类型的对象,不能直接使用对应的运算符来进行操作,比如判断两个对象是否相等,因此,为了增加代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。

函数原型:返回值类型 operator操作符(参数列表)

注意:

不能通过连接其他符号来创建新的操作符:比如operator@ ,重载的操作符必须是C++ 中支持的

重载操作符必须有一个类类型或者枚举类型的操作数,必须有一个自定义类型的参数

用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义

作为类成员的重载函数时,其形参看起来比操作数数目少1成员函数的

操作符有一个默认的形参this,限定为第一个形参

.* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。

    赋值运算符必须重载成类的成员函数,因为赋值运算符重载是默认成员函数,如果用户没有显式定义,编译器会默认生成一份,如果重载成了全局函数,会和默认生成的产生冲突

赋值运算符主要注意四点:参数类型、返回值、检测是否自己给自己赋值、返回*this

重载前置++/--和后置++/--时,为了使两个运算符形成重载,后置++/--多引入一个int类型的参数

class Date //赋值运算符重载
{
	Date& operator=(const Date& d)//返回值是为了支持连续赋值,引用是为了提高效率
 //成员函数默认存在一个this指针,首先检测是否自己给自己赋值
//const 是为了保护参数
	{
		if (this != &d)
		{
			_year = d.year;
			_month = d.month;
			_day = d.day;
		}
		return *this;
	}
    Date& operator++(){}//前置++
    Date& operator++(int){}//后置++
};

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值