类和对象下

96 阅读2分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。


初始化列表

为什么要引用初始化列表?因为对于一些==引用类型==,==const修饰的类型==,==自定义类型==(特别是类中没有默认的构造函数)的时候。单靠在构造函数内部实现是不可能完成的。而初始化列表就可以解决这些问题。

它的形式是在函数后面加上:,有多个变量的时候以,分割。:类的成员(初始化), ,

class Time
{
public:
	Time(int hour)//此处非默认构造函数
	{
		_hour = hour;
	}
private:
	int _hour;
};
class Date
{
public:
	Date(int year)
		:_year(year)
		, _a(0)//该成员必须用初始化列表进行初始化
	{}
private:
	int _year;
	Time _a;
};

初始化列表可以理解为成员变量定义的地方。

  • 成员变量声明的顺序是初始化的顺序。

    class f
    {
    public:
    	f()
    		:B(1)
    		,A(B)
    	{
    		cout << A << ' ' << B << endl;
    	}
    private:
    	int A;
    	int B;
    };
    

从输出的结果中就可以看出来在这里插入图片描述

explicit关键字

取消对隐式类型的转换,对与单参数(下面的这种)或者第一个参数没有初始值(如:Date (int year, int month=0,int day=0)) 例:

class Date
{
public:
	explicit Date(int year=1)
		:_year(year)
	{}
private:
	int _year;

};
int main()
{
	Date a;
	a = 2022;//错误
	return 0;
}

这里的2022需要进行隐式转换,转换成Date类型,然后进行赋值操作。然而用explicit关键字可以阻止这中转换。此时那种转换就不正确了。

static

static成员变量

static成员变量是静态变量,属于所有对象共享资源,静态的变量不能在构造函数(初始化列表)中进行定义。因为静态的木有this指针,它在全局进行定义。非静态的还是用构造函数进行初始。

class Date
{
public:
	Date()
		:_month(1)
	{}
private:
	static int _year;
	int _month;
};
int Date::_year = 1;

static成员函数

static成员函数也是所以对象共享的成员,在此函数里面只能访问静态的成员,因为没有this指针。该成员函数的访问有两种方式:类名::函数对象.函数

class Date
{
public:
	Date()
		:_month(1)
	{}
	static void Print()
	{
		cout << _year;
	}
private:
	static int _year;
	int _month;
};
int Date::_year = 1;
int main()
{
	Date a;
	a.Print();
	Date::Print();
	return 0;
}

友元

关键字friend

友元函数

<<运算符重载的时候,<<左边是流,右边是对象,在重载的时候因为第一个参数为this指针,会导致类型不匹配。除了写成全局的函数外,还可以用友元函数进行处理,设置成友元的时候,就没有了this指针了,就可以改变第一个参数了(即不然他为this指针)。 友元函数不属于任何类的成员,和普通的函数几乎没有区别。 类的友元函数可以访问私有成员。声明在类的类别,在类的外面进行定义。 下面这个是<<的运算符重载。

class Date
{
	friend ostream& operator<<(ostream& a, Date& b);
public:
	Date()
		:_year(1)
		,_month(1)
	{}
private:
	int _year;
	int _month;
};
ostream& operator<<(ostream& a, Date& b)
{
	cout << b._year << ' ' << b._month;
	return a;
}

友元类

假如A是B的友元类,在B中可以访问A的私有成员。

class B
{
	friend class A;
private:
	int _b = 2;
};
class A
{	
public:
	void Print(B b)
	{
		cout << _a<< ' ' <<b._b  << endl;
	}
private:
	int _a=1;
};
int main()
{
	A().Print(B());//匿名对象
	return 0;
}

在这里插入图片描述

内部类

内部类就是在一个类的里面再定义一个类,这就叫内部类。内部类是外部类的友元,即在内部类中可以访问外部类的私有成员。

class A
{
	class B
	{
	public:
		B()
			:_b(0){}
		void Print(A a)
		{
			cout << a._a;
		}
	private:
		int _b;
	};
public:
	A()
		:_a(0){}
private:
	int _a;
};