一、内容概要
1.数据成员初始话
初始化表达式
2.类的特殊成员
const数据成员
引用成员
static 数据成员
类对象成员
const 修饰函数
static 修饰函数
3.友元函数
二、类的特殊成员
1.const数据成员
1.赋值用初始化表达式的方式进行赋值
2.如果构造函数重载,所有的构造函数对于const成员都要进行初始化
3.const成员如果直接使用=赋值,那就可以不用初始化表达式
例子:
#include<iostream>
using namespace std;
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();
return 0;
}
例子2:const成员如果直接使用=赋值,那就可以不用初始化表达式
const int zp = 100;
2.引用成员
给变量起别名,一般用在传参
引用定义的时候必须初始化
类中有引用成员如何赋值? 初始化表达式赋值
例子:
class Point
{
private:
int xp;
int yp;
int &zp; //定义引用成员
public:
Point(int x,int y,int &z):xp(x),yp(y),zp(z)//再函数重载中进行初始化赋值操作
{
}
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;
4.对象成员---组合
举例:一个猫类中,有头类,身体类和脚类 而头类,身体类,脚类都可以是猫类中的类
例子:
#include<iostream>
using namespace std;
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;
}
};
int main()
{
Head h1;
Body b1;
Foot f1;
Human people(h1,b1,f1);
return 0;
}
如果使用到指针的话,需要用到new函数进行开空间,那么就要注意需要使用析构函数进行动态内存空间的清除。
例如:
public:
Head *h;
Body *b;
Foot *f;
Human()
{
h = new Head;
b = new Body;
f = new Foot;
}
~Human()
{
delete h;
delete b;
delete f;
}
};
5.const成员的函数
成员函数:
数据类型 函数名(形参) const
{
}
这个函数只能读,不能写
6.static成员函数
静态成员:属于类,可以使用对象进行调用,也可以使用类直接调用 类名::函数名(实参列表);
静态成员函数内只能调用静态成员函数
静态成员函数中只能访问静态数据,所以静态成员函数就是为了访问静态成员设计的
不要再用初始化表达式赋值
三、友元函数
突破private限制,可以让外部函数访问类内的私有成员
格式:
返回值类型 函数名(const 类名 &引用名)
{
}
在要访问私有成员的类里面要证明这个函数是这个类的朋友:
friend 返回值类型 函数名(const 类名 &引用名);
分类:
1、可以将外部函数定义为一个类的友元
2、一个类的成员函数定义为另一个类的友元
3、定义友元类
1的例子:
#include<iostream>
using namespace std;
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);
return 0;
}
例子:一个B类的成员函数定义为另一个A类的友元函数
1、声明A类型
2、在B类的成员函数要声明和定义分开,定义要在A类下面
3、在A类型声明友元同时在函数名加 B::
4、需要特别注意程序运行顺序的问题
// 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 ,....
}
例子:友元 遇到函数重载,只有声明朋友的那个函数才可以访问,没有声明的不行
#include<iostream>
#include<cmath>
using namespace std;
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;
}
int main()
{
Point a(1,3);
Point b(2,4);
Line l;
float res = l.distance(a,b);
cout << res << endl;
return 0;
}
**************************************************************************************************************总结:
类里面的特殊成员
const数据成员
引用成员
static成员
类对象成员
const成员函数
static成员函数
友元函数
突破private限制
返回值类型 函数名(const 类名 &引用名)
{
}
返回值类型 类名::函数名(const 类名 &引用名)
{
}
在要访问私有成员的类里面要证明这个函数是这个类的朋友:
friend 返回值类型 函数名(const 类名 &引用名);