C++类的特殊成员&&友元函数

C++类的特殊成员&&友元函数

1、类的特殊成员

1.1 const 数据成员

  • 赋值用初始化表达式的方式进行赋值
  • 如果构造函数重载,所有的构造函数对于const成员都要进行初始化
  • const成员如果直接使用=赋值,那就可以不用初始化表达式

例一:

class Point
{
private:
	int xp;
	int yp;
	const int zp;
public:
	Point(int x,int y,int z):xp(x),yp(y),zp(z)
	{
//		xp = x;
//		yp = y;
//		zp = z;  // 报错:在这里写是相当于对zp进行赋值
	}
	Point() {}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}	
}; 
int main()
{
	Point a(1,2,3);
	a.show();  //xp:1,yp:2,zp:3
	return 0;
}

例二:

const成员如果直接使用=赋值,那就可以不用初始化表达式

class Point
{
private:
	int xp;
	int yp;
	const int zp = 100;
public:
	Point(int x,int y)
	{
		xp = x;
		yp = y;
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}	
}; 
int main()
{
	Point a(1,2);
	a.show();
	return 0;
}

1.2 const 成员的函数

成员函数:

数据类型 函数名(形参) const

{

}

这个函数只能对成员进行读操作,不能对成员进行写操作

如果在这个函数内部只能调用其他const成员函数

例:

class Point
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void test1(void)
	{
		cout << "无cosnt函数" << endl;
	}
	
	void test2(void) const
	{
		cout << "有const的函数 " << endl;
	}
	
	void show(void) const
	{		
		test2();
		cout << "xp:" << xp << ",yp:" << yp << endl;
	}	
};
int main()
{
	Point a(3,4);
	a.show(); // 有const的函数 
			  // xp:3,yp:4	
	return 0;
}

1.3 static 数据成员

  • static:静态区,程序加载的时候空间就分好了。
  • static数据成员在类中所有对象共享,在类外使用:数据类型 类名::静态成员名 = 值;
  • static数据成员不能使用this进行操作

例:static数据成员在类中多有对象共享

class Point
{
private:
	int xp;
	int yp;
	static int zp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}	
};
int Point::zp = 100; //初始化
int main()
{
	Point a(1,2);
	a.show(); // xp:1,yp:2,zp:100
	
	Point b(3,4);
	b.show();// xp:3,yp:4,zp:100		
	
	return 0;
}

1.4 static 成员函数

  • 静态成员:属于类 ,可以使用对象进行调用,也可以使用类直接调用 类名::函数名(实参列表);
  • 静态成员函数内只能调用静态成员函数
  • 静态成员函数中只能访问静态数据,所以静态成员函数就是为了访问静态成员设计的。
  • 不要在用初始化表达式赋值。

例:

class Point
{
private:
	int xp;
	int yp;
	
	static int zp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	
	void test1(void)
	{
		cout << "无static函数" << endl;
	}
	
	static void test2(void) 
	{
		cout << "有static的函数 " << endl;
	}
	
	static void show(void) 
	{
		// 调用test1失败		
		test2();
		cout << "show方法,zp:" << zp << endl;
		zp = 800
		cout << "show方法,zp:" << zp << endl;		
	}	
};
int Point::zp = 500; //初始化
int main()
{
	Point a(3,4);
	a.show(); //有static的函数
			  //show方法,zp:500
			  //show方法,zp:800
	Point::show(); //同上
	
	
	return 0;
}

1.5 引用成员

  • 给变量起别名,一般用在传参

  • 引用定义的时候必须初始化

    类中有引用成员如何赋值?-- 初始化表达式赋值

class Point
{
private:
	int xp;
	int yp;
	int &zp;  //定义引用成员
	
public:
	// 错误的初始化因为在构造函数{}内属于赋值不属于初始化 
	Point(int x,int y,int &z)
	{
  		xp = x;
		yp = y;
		zp = z;  
	}
    
    //正确的初始化
	Point(int x,int y,int &z):xp(x),yp(y),zp(z)
	{
			
	}	
				
	void show(void)
	{
		cout << "xp:" << xp << ",yp:" << yp << ",zp:" << zp << endl;
	}
}; 

1.6 对象成员 – 组合

例如:

人类:头类 身体类 脚类

class Head
{
public:
	Head()
	{
		cout <<  " ○"  << endl;
	}	
};

class Body
{
public:
	Body()
	{
		cout << "  | "	<< endl;
		cout << " |-|"   << endl; 
	}		
};

class Foot
{
public:
	Foot()
	{
		cout << " _ _" << endl; 
	}	
};

class Human
{
public:
	Head h;
	Body b;
	Foot f;
	
	Human(Head &h,Body &b,Foot &f)
	{	
		this->h = h;
		this->b = b;
		this->f = f;			
	} 
}; 

指针写法

class Human
{
public:
	Head *h;
	Body *b;
	Foot *f;
	
	Human()
	{	
		h = new Head;
		b = new Body;
		f = new Foot;			
	} 
	
	~Human()
	{
		delete h;
		delete b;
		delete f;
	} 
}; 

2、友元函数

突破private限制,可以让外部函数访问类内的私有成员。

格式:

返回值类型 函数名(const 类名 &引用名)

{

}

在要访问私有成员的类里面要证明这个函数是这个类的朋友:

格式:

friend 返回值类型 函数名(const 类名 &引用名);

分类:

  • 可以外部函数定义为一个类的友元
  • 一个类的成员函数定义为另一个类的友元
  • 定义 友元类

例一:一个外部函数访问类内的私有成员

class Point
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y){
	}
	// 声明printP是Point的朋友
	friend  void printP(const Point &p1);
};
// 定义一个外部函数想要访问类对象里面的私有成员xp; 
void printP(const Point &p1)
{
	cout << p1.xp << endl;
}
int main()
{
	Point a(1,3);
	
	printP(a); // 1
	return 0;
}

例二:

一个B类的成员函数定义为另一个A类的友元函数

1、声明A类型

2、在B类的成员函数要声明和定义分开,定义要在A类的下面

3、在A类型声明友元同时在函数名加 B::

// A找不到 -- 程序顺序问题 -- 声明A类
class A;		

class B
{
public:
	float distance(A &a,A &b);  // 只能声明
	
};

class A
{
private:
	int xp;
	int yp;
public:
	A(int x,int y):xp(x),yp(y){};
	// 声明朋友
	friend float B::distance(A &a,A &b);
};
	
// 在A类的下面定义函数
float B::distance(A &a,A &b)
{
	// a.xp  a.yp  ,....
}

例三:友元 遇到函数重载,只有声明朋友的那个函数才可以访问,没有声明的不行

class Point;

class Line
{
public:
	float distance(Point &a,Point &b);
	float distance(Point &a); 
};
class Point 
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y)
	{
		
	}	
	// 两个都声明才可以用
	friend float Line::distance(Point &a,Point &b);
	friend float Line::distance(Point &a); 
};
float Line::distance(Point &a,Point &b)
{
	float d;
	d = sqrt((a.xp-b.xp)*(a.xp-b.xp) + (a.yp-b.yp)*(a.yp-b.yp));
	return d;
}	

float Line::distance(Point &a)
{
	cout << "重载distance " << a.xp << endl;
	return 1.0;
}

例四:友元类 — 将整个类声明为友元

//接例三  
class Point 
{
private:
	int xp;
	int yp;
public:
	Point(int x,int y):xp(x),yp(y)
	{
		
	}	
	
	//friend float Line::distance(Point &a,Point &b);
	//friend float Line::distance(Point &a); 
	friend Line;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值