类和对象(三)

构造函数初始化

(一)初始化列表以冒号开始,逗号分隔的数据成员列表。数据成员后面括号写初始值或表达式。

class Date {
	//构造函数
public:
	Date(int year, int month, int day) 
		:_year(year) ,
		_month(month),
		_day(day)
	{}
private:
	int _year;
	int _month;
	int _day;
};

每个成员变量在初始化列表中只能出现一次。
在这里插入图片描述
对于成员变量初始化,在构造函数中直接赋值,为什么还要写初始化列表?因为初始化只能初始化一次,而构造函数体内可以多次赋值。在类中包含以下成员,必须放在初始化列表位置进行初始化。
(1)引用成员变量

class A
{
public:
	A(int a) 
	:_a(a)
	{
		cout << "A(int a)" << endl;
	}
private:
	int _a;
	int& _ret;
};

在这里插入图片描述
(2)const成员变量


class A
{
public:
	A(int a,int ref) 
	:_a(a),
	_ret(ref)
	{
		cout << "A(int a)" << endl;
	}
private:
	int _a;
	int& _ret;
	const int _b;
};

在这里插入图片描述
(3)自定义类型成员(且该类没有默认构造函数)

class B {
public:
	B(int b) 
		:_c(5)
	{
		cout << "B()" << endl;
	}
private:
	int _c;
};
class A
{
public:
	A(int a,int ref,int c) 
	:_a(a),
	_ret(ref),
	_b(5)
	{
		cout << "A(int a)" << endl;
	}
private:
	int _a;
	int& _ret;
	const int _b;
	B aa;
};

在这里插入图片描述
在这里插入图片描述
(二)尽量使用初始化列表,无论是否使用初始化列表,对于自定义类型的成员变量,一定会使用成员列表进行初始化。

(三)成员变量在类中声明的次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的次序无关。

class A {
public:
	A(int a)
		:_a1(a),
		_a2(_a1)
	{}
	void Print() {
		cout << _a1 << " " << _a2 << endl;
	}
private:
	int _a2;
	int _a1;
};
int main() {
	A aa(1);
	aa.Print();
	return 0;
}

在这里插入图片描述
先声明a2,所以先初始化a2,将a1赋值给a2,此时a1是随机值,所以a2是随机值。再声明a1,将a赋值给a1,所以a1是1。

static成员

(一)概念
类的静态成员:static的类成员用
静态成员变量:static修饰的成员变量
静态成员函数:static修饰的成员函数
静态成员变量一定要在类外进行初始化。

class A {
public:
	A(int a=0) {
		count++;
		cout << "A(int a=0)" << endl;
    }   
	A(const A& a) {
		count++;
		cout << "A(const A& a)" << endl;
	}
	static int GetCount() {
		//_a++; 错误的,不能访问非静态成员
		return count;
	}
private:
	static int count;  //声明
	int _a;
};
int A::count= 0;  //在类外定义初始化
int main() {
	A aa;
	cout << A::GetCount() << endl;
	cout << aa.GetCount() << endl;
}

(二)静态成员特性

  1. 静态成员为所有类成员对象共享,不属于某个具体的对象,存放在静态区。
  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明。
  3. 类静态成员用类名::静态成员或者对象.静态成员来访问。
  4. 静态成员函数中没有隐藏的this指针,不能访问非静态成员。
  5. 静态成员也是类的成员,受public,protected,private访问限定符的限制。

友元

友元函数

友元函数直接访问类的私有成员,它是定义在类外部的普通函数,但在类的内部要声明,声明时需要加上friend关键字。

//输入,输出类
class Date
{
	friend istream& operator>>(istream& cin, Date& d);
	friend ostream& operator<<(ostream& cout, const Date& d);
public:
	Date(int year=2023,int month=2, int day=2) 
		:_year(year),
		_month(month),
		_day(day)
	{}

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

//输入
istream& operator>>(istream& cin, Date& d) {
	cin >> d._year;
	cin >> d._month;
	cin >> d._day;
	return cin;
}

//输出
ostream& operator<<(ostream& cout, const Date& d) {
	cout << d._year << "年" << d._month << "月" << d._day << "日";
	return cout;
}
int main() {
	Date d;
	cin >> d;
	cout << d << endl;
	return 0;
}
  1. 友元函数可以访问类的私有成员,但不是类的成员函数。
  2. 友元函数不能用const修饰。
  3. 友元函数可以在类的任何地方声明,不受访问限定符的限制。
  4. 一个函数可以是多个类的友元函数。

友元类

友元类的所有成员函数都可以是另一个类的成员函数,都可以访问另一个类的非公有成员。

class Date
{
	friend class Time;
public:
	Date(int year = 2023, int month = 2, int day = 2)
		:_year(year),
		_month(month),
		_day(day)
	{}

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

class Time
{
public:
	Time(int hour = 0, int minute = 0, int second = 0)
		:_hour(hour),
		_minute(minute),
		_second(second)
	{}
	void SetDateOfTime(int year, int month, int day) {
		_t._year = year;
		_t._month = month;
		_t._day = day;
	}
private:
	int _hour;
	int _minute;
	int _second;
	Date _t;
};

在Date类中声明Time为其友元类,那么在Time类中直接访问Date类的私有成员变量,但Date类中访问Time类的私有成员变量不可以。

匿名对象

class  A
{
public:
	 A(int a=10)
	  :_a(a)
	 {}
	 void Print() {
		 cout << _a << endl;
	 }
private:
	int _a;
};
int main() {
	A(); //生成一个匿名对象,生命周期只有这一行
	A aa(20);
	A ret = A(20);
	//首先生成一个匿名对象,将匿名对象变为ret对象
	//生命周期是ret的生命周期
	A().Print();

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值