C++类的六个默认成员函数

【this指针】:

1.每个成员函数都有一个指针形参,它的名字是固定的,成为this指针,this指针是隐式的,(构造函数比较特殊,没有这个隐含this形参)。

2.类型: 类类型* const

3.this指针并不是对象本身的一部分,不影响sizeof的结果

4.this指针是”类成员函数”的第一个默认隐含参数,编译器自动维护传递,类编写者不能显式传递

5.只有在类的非静态成员函数中才可以使用this指针,其它任何函数都不可以



1.【构造函数】

构造函数(constructor)是一个特殊的成员函数,名字与类名相同,创建类类型对象时,由编译器自动调用,在对象的生命周期内只调用一次,保证每个数据成员都有
一个合适的初始值

构造函数是特殊的成员函数,其特征如下:
1. 函数名与类名相同。
2. 无返回值。
3. 对象构造(对象实例化)时系统自动调用对应的构造函数。且在对象的声明周期内仅调用
一次.
4. 构造函数可以重载。
5. 构造函数可以在类中定义,也可以在类外定义。
6. 如果类定义中没有给出构造函数,则C++编译器自动产生一个缺省的构造函数,但只要我们定义了一个构造函数,系统就不会自动
生成缺省的构造函数。

7. 无参的构造函数和全缺省值的构造函数都认为是缺省构造函数,并且缺省的构造函数只能有一个。

8.构造函数不能为虚函数

Date(int year = 1900, int month = 1, int day = 1)	//全缺省构造函数
{
	_year = year;
	_month = month;
	_day = day;
}

2.【拷贝构造函数】
只有单个形参,而且该形参是对本类类型对象的引用(常用const修饰),这样的构造函数称为拷贝构造函数。拷贝构造函数是特殊的构造函数,创建对象时使用已存在的同类对象来进行初始化,由编译器自动调用
特征:
1. 拷贝构造函数其实是一个构造函数的重载。构造函数的性质拷贝构造均满足
2. 拷贝构造函数的参数必须使用引用传参,指针也不行,使用传值方式会引发无穷递归调用。(把形参复制到实参会调用拷贝构造,如果进行值传递,就会在拷贝构造函数内调用拷贝构造函数。)这里传引用,并不是为了减少内存拷贝。

举个例子:

Date s2(s1);

拷贝构造函数:Date (Date t);   这里进行传值的话,因为要构造 t 就会产生Date t (s1),再将s1传值给拷贝构造函数,又因为同样的原因,再次产生Date t (s1);

3. 若未显示定义,系统会默认缺省的拷贝构造函数。缺省的拷贝构造函数会依次对拷贝类成员进行初始化。

构造函数使用的场景:

1>显式或隐式地用同类型的一个对象来初始化另外一个对象。如:Date a; Date b(a);

2>作为实参传递给一个函数。

3>在函数体内返回一个对象时,也会调用返回值类型的拷贝构造函数.。

Date(const Date& d)
{
	_year = d._year;
	_month = d._month;
	_day = d._day;
}

3.【析构函数】

当一个对象的生命周期结束时,C++编译系统会自动调用一个成员函数,这个特殊的成员函数即析构函数(destructor)
构造函数是特殊的成员函数,其特征如下:
1. 析构函数在类名加上字符~。
2. 析构函数无参数无返回值。
3. 一个类有且只有一个析构函数。若未显示定义,系统会自动生成缺省的析构函数。
4. 对象生命周期结束时,C++编译系统系统自动调用析构函数
5. 注意析构函数体内并不是删除对象,而是做一些清理工作。

class Array
{
public :
	Array (int size)
	{
		_ptr = (int *)malloc( size*sizeof (int));
		assert(_ptr);
	}
	// 这里需要析构函数释放空间
	~ Array ()
	{
		if (_ptr )
		{
			free(_ptr );
			_ptr = 0;
		}
	}
private :
	int* _ptr ;
};

4.【运算符重载】
为了增强程序的可读性,C++支持运算符重载。
运算符重载特征:
1. operator+合法的运算符构成函数名(重载<运算符的函数名:operator<)。
2. 重载运算符以后,不能改变运算符的优先级/结合性/操作数个数。

5个C++不能重载的运算符:        .*    ::          sizeof       ? :           .

赋值运算符重载:

拷贝构造函数是创建的对象,使用一个已有对象来初始化这个准备创建的对象。
赋值运算符的重载是对一个已存在的对象进行拷贝赋值

Date& operator=(const Date& d)	//赋值运算符的重载  >>  返回引用,防止连续赋值
{
	if (this != &d)		//检测是否是自身赋值
	{
		this->_year = d._year;
		this->_month = d._month;
		this->_day = d._day;
	}
	return *this;
}

类的成员变量有两种初始化方式:
1. 初始化列表。
2. 构造函数体内进行赋值。
初始化列表以一个冒号开始,接着一个逗号分隔数据列表,每个数据成员都放在一个括号中进行初始化。尽量使用初始化列表进行初始化,因为它更高效

哪些成员变量必须放在初始化列表里面?
1. 常量成员变量。(常量创建时必须初始化)
2. 引用类型成员变量。(引用创建时必须初始化)
3. 类类型成员(该类有非缺省的构造函数)

成员变量按声明顺序依次初始化,而非初始化列表出现的顺序

取地址操作符的重载和const取地址操作符的重载: 一般不建议重载。系统默认生成的足够使用。

自己写可以设置是否允许取得类的地址,以此防止其他函数通过取地址修改原本不应被修改的类的成员。


什么情况下类才会真正的合成构造函数、拷贝构造函数及赋值运算符的重载?

类的类成员有缺省的构造函数,因为要构造该类成员就必调用该类的构造函数,且该类的初始化必须放在初始化列表中。

当成员为内置类型时,类不会合成默认的构造函数:


类的类成员有缺省的构造函数,类会自动合成构造函数。



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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值