初始化列表+explicit关键字+友元+static关键字

一、初始化列表

1.初始化列表的定义

初始化列表是构造函数中以冒号开始,中间用逗号分隔成员变量初始化表达式的列表。

2.初始化列表的用法

class date
{
public:
	date()
		:_year(2024),
		_month(1),
		_day(1)
	{

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

在构造函数后面用冒号开始,成员变量后括号内是初始化的值,用逗号分隔。

注意点:

1.初始化列表与构造函数并不冲突,事实上无论你写不写初始化列表,调用构造函数时编译器都会走一遍初始化列表,并且对自定义类型调用它的构造函数进行初始化。

class date
{
public:
	date()
		:
		_year(2024),
		_month(1)
	{
		_day = 6;
	}
	
private:
	int _year;
	int _month;
	int _day;
};

下面我们并不写包含自定义变量的初始化列表,在默认构造函数中也不对自定义类型的对象赋值

class A
{
public:
	A()
	{
		a = 1;
		b = 2;
	}
	int a;
	int b;
};
class date
{
public:
	date()
		:_year(2024),
		_month(1),
		_day (1)
	{
	}
private:
	int _year;
	int _month;
	int _day;
	A _t;
};

我们会发现_t中的a,b仍然会被分别初始化为1和2。

2.初始化列表初始化成员变量的顺序是按照成员变量声明的顺序。

class A
{
public:
	A(int t)
		:b(t),
		a(b)
	{
	}
private:
	int a;
	int b;
};
int main()
{
	A t(3);
	return 0;
}

对于上述代码,a的值为随机值,b的值为1。因为初始化列表先用b初始化a,而此时b为随机值,之后才用t初始化b。

3.初始化列表初始化成员变量只能初始化一次,不能重复初始化。

4.成员声明处的缺省值是为初始化列表服务的。

3.初始化列表的意义

因为成员变量的初始化只能在初始化列表中进行(构造函数不能算初始化),所以对于const修饰的成员变量、对某类型引用的成员变量、没有默认构造的自定义类型的成员变量必须使用初始化列表初始化。实际来说,我们应该尽量用初始化列表来初始化成员变量。

二、explicit关键字

隐式类型转换:

当我们用常量来赋值类的时候,会发生隐式类型转换。

class A
{
public:
	A(int t)
	{
		_a = t;
	}
private:
	int _a;
};
int main()
{
	A m = 3;
	return 0;
}

编译器会先用3生成一个具有常性的临时变量,再将临时变量拷贝构造给m。

如果类有多个成员变量,可用大括号括起来。

class A
{
public:
	A(int x,int y)
	{
		_a = x;
		_b = y;
	}
private:
	int _a;
	int _b;
};
int main()
{
	A m = { 1,2 };
	return 0;
}

用法:

explicit放在构造函数前,可防止隐式类型转换的发生。

此时会发现编译器报错。

三、友元

1.友元的定义

友元是一种定义在类外部的普通函数或类,但它需要在类体内进行说明,为了与该类的成员函数加

以区别,在说明时前面加以关键字friend。友元不是成员函数,但是它可以访问类中的私有成员。

2.友元的用法

对于类中的私有成员,在类外我们无法访问,因此需要友元来帮助我们访问。

2.1 全局函数作友元

在类内声明该全局函数,并在返回值前加上关键字friend,这样全局函数就能访问类内私有成员了。

class date
{
	friend void print(date& v);
public:
	date()
		:
		_year(2024),
		_month(1),
		_day(1)
	{		
	}
private:
	int _year;
	int _month;
	int _day;
};
void print(date &v)
{
	cout <<v._year<< "年" << v._month << "月" << v._day << "日" << endl;
}

2.2 类作友元

在类内声名类,并在之前加上关键字friend,这样被声明的类就可以访问该类的私有成员了。

class A
{
	friend class B;
public:
	A()
	{
		a = 1;
		b = 2;
	}
private:
	int a;
	int b;
};
class B
{
public:
	void print()
	{
		cout << t.a << " " << t.b << endl;
	}
private:
	A t;
};

2.3 内部类

类中可以定义类,定义的类是独立的类,只受类域和外部类访问权限的限制。

内部类天生就是外部类的友元。

class A
{
private:
	int a;
	int b;
public:
	A()
	{
		a = 1;
		b = 2;
	}
	class B
	{
	public:
		void print(A& v)
		{
			cout << v.a << " " << v.b << endl;
		}
	private:
		int b;
	};
};

四、C++类中static关键字

1.static修饰成员变量

static修饰成员变量时,该成员变量储存区域由栈区改为静态区,生命周期延长,该类实例化的所有对象共用该成员变量。

static修饰的成员变量初始化在类外部。

class A
{
public:
	A()
	{
		b = 2;
	}
private:
	static int a;
	int b;
};
int A::a = 1;

2.static修饰成员函数

static修饰成员函数时,该成员函数没有this指针,只能访问该类的静态成员变量。

class A
{
public:
	static void print()
	{
		cout << a << endl;
	}
private:
	static int a;
};
int A::a = 1;

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值