目录
1 封装
1.1 封装的意义
封装是C++面向对象三大特性之一
1.2 语法
class name
{
访问权限:
属性
行为
};
注意:类中的属性和行为 统称为成员
-
属性 又称 成员属性 / 成员变量
-
行为 又称 成员函数 / 成员方法
封装将属性和行为作为一个整体,表现生活中的事物
1.3 示例
1.3.1 示例1
接下来创建一个圆类,以计算圆的周长
创建圆类:
// 创建一个 圆 类,class后跟着的就是类的名称
class Circle
{
// 访问权限
public:// 公共权限
// 属性
int r; // 半径
// 行为
double caculate_perimeter() // 计算圆的周长
{
return 2 * PI * r;
}
};
主函数
实例化:通过类创建一个对象的过程
#define PI 3.14
int main()
{ // 实例化:通过类创建一个对象的过程
Circle c; // 通过 圆 类创建具体的圆(对象)
cin >> c.r; // 给 圆 对象 的属性赋值
cout << "半径为" << c.r << "的圆的周长为" << c.caculate_perimeter() << endl;
return 0;
}
1.3.2 示例2
设计一个学生类,属性有姓名和学号,行为可以给学生姓名和学号赋值,而且可以显示学生姓名和学号
class student
{
public:
// 属性:姓名 学号
string s_name;
int s_number;
// 行为:给姓名与学号赋值/显示
void show()
{
cout << "学生姓名为" << s_name << endl;
cout << "学生学号为" << s_number;
}
// 赋值
void assignment1() // 键盘输入
{
cout << "请输入姓名" << endl;
cin >> s_name;
cout << endl;
cout << "请输入学号" << endl;
cin >> s_number;
}
void assignment2(string name,int Studnet_number)// 直接传参
{
s_name = name;
s_number = Studnet_number;
}
};
对于给姓名和学号赋值,有2种方法
-
直接键盘cin
-
调用函数时直接传参
方法不同,调用函数时写法也不同
int main()
{
student s1;
s1.assignment1(); //1键盘cin输入
s1.assignment2("joyce", 32054123); // 2直接传参
s1.show();
return 0;
}
1.4 将属性和行为加以权限控制
类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有3种:
名称 | 作用范围 | 不同点 | |
---|---|---|---|
public | 公共权限 | 类内可以访问,类外可以访问 | \ |
protected | 保护权限 | 类内可以访问,类外不可以访问 | 继承关系中,子可以使用父的 |
private | 私有权限 | 类内可以访问,类外不可以访问 | 继承关系中,子不能使用父的 |
示例:
class person
{
public:
string name;// 姓名,公共权限
protected:
string car;// 汽车,保护权限
private:
int password;// 密码,私有权限
};
int main()
{
person p;
p.name = "joyce";// 只有公共权限在类外才可以访问
p.car = "BMW";
p.password = 131221;
return 0;
}
不过,如果在类内定义一个公共权限的函数,以访问各个权限的属性,则
class person
{
public:
string name;// 姓名,公共权限
protected:
string car;// 汽车,保护权限
private:
int password;// 密码,私有权限
public: //类内定义的公共权限的函数
void func()
{
string name = "nana";
string car = "BMW";
int password = 19931312;
}
};
在main函数中调用func函数,则可以访问保护权限和私有权限的属性
p.func();
不过若是将函数的权限从public改为protected或是private,则仍然无法访问
1.5 struct与class的区别
区别仅在于 默认的访问权限不同
名称 | 默认访问权限 | |
---|---|---|
struct | public | 公共权限 |
class | private | 私有权限 |
1.5.1 示例
创建struct和class两个类型
struct P1
{
int a;
};
class P2
{
int a;
};
在main函数中
创建变量并尝试访问
int main()
{
P1 p1; // 结构体
p1.a = 5;
P2 p2; // 类
p2.a = 5;
return 0;
}
1.6 成员属性设置为私有
作用:
-
可以自己控制成员的读写权限
class My
{
public:
void setname(string name)// 设置姓名
{
m_name = name;
}
string getname() // 返回姓名
{
return m_name;
}
int getage() // 返回年龄,无法修改
{
return age;
}
void setPassword(int password) // 修改密码,无法查看
{
m_Password = password;
}
private:
string m_name; // 设置为可读可写
int age = 5; // 设置为只读
int m_Password; // 设置为只写
};
接下来使用各个函数,修改或查看各个属性
int main()
{
My m;
m.setname("joyce"); // 设置姓名
cout << m.getname() << endl; // 查看姓名
cout << m.getage() << endl;// 查看年龄
//m.age = 6; // 若想修改年龄,无法访问
m.setPassword(3171321); // 修改密码,无法查看
m.m_Password;
return 0;
}
而可读可写权限的姓名,可以修改或是查看
-
对于写可以检测数据的有效性
在上面类中,我们在查看年龄getage函数下,加上设置年龄setage函数
void setage(int age) // 设置年龄,范围0-150
{
if (age < 0 || age>150)
{
cout << "Input errot!" << endl;
m_age = 0;
return;
}
m_age = age;
}
并加以判断,若年龄不在0-150,则报错,满足才修改年龄
1.7 示例
1.7.1 示例1
设计一个正方体类,获取正方体长宽高,计算出正方体面积和体积,并分别用全局函数和成员函数判断两个立方体是否相等
class Cube
{
public:
// 设置与获取长宽高
void setCube(int L, int W, int H)
{
m_L = L;
m_W = W;
m_H = H;
}
int getL()
{
return m_L;
}
int getW()
{
return m_W;
}
int getH()
{
return m_H;
}
// 获取正方体面积
int calculateArea()
{
return 2 * (m_L * m_W + m_L * m_H + m_W * m_H);
}
// 获取正方体体积
int calculateVolume()
{
return m_L * m_W * m_H;
}
//2、用成员函数判断2个Cube是否相等
bool Judge2(Cube& cube)
{
if (getH() == cube.getH() &&
getL() == cube.getL() &&
getW() == cube.getW())
return true;
return false;
}
private:
int m_L, m_W, m_H;
};
// 1、用全局函数判断2个Cube是否相等
bool Judge1(Cube&cube1 ,Cube&cube2)
{
if (cube1.getH() == cube2.getH() &&
cube1.getL() == cube2.getL() &&
cube1.getW() == cube2.getW())
return true;
return false;
}
int main()
{
// 创建第一个Cube
Cube cube1;
cube1.setCube(10,10,10);
/*cout << "正方体面积为" << cube1.calculateArea() << endl;
cout << "正方体体积为" << cube1.calculateVolume() << endl*/;
// 创建第二个Cube
Cube cube2;
cube2.setCube(10, 10, 10);
bool ret1 = Judge1(cube1,cube2); // 全局变量调用的对比
if (ret1)
cout << "cube1和cube2相等" << endl;
else
cout << "cube1和cube2不相等" << endl;
bool ret2 = cube1.Judge2(cube2); // 成员函数调用的对比
if (ret2)
cout << "cube1和cube2相等" << endl;
else
cout << "cube1和cube2不相等" << endl;
return 0;
}
两函数都相等
两函数都不相等
1.7.2 示例2
设计一个圆类和点类,属性包括圆和点的横坐标x和纵坐标y以及两点之间距离和圆的半径,并判断点在圆的什么位置(上、内、外)
点类:point.h
头文件
class point // 点 类
{
public:
void setx(int x); // 设置点的横坐标x
int getx();
void sety(int y);// 设置点的纵坐标y
int gety();
private:
int p_x;
int p_y;
};
源文件:point.cpp
void point::setx(int x) // 设置点的横坐标x
{
p_x = x;
}
int point::getx()
{
return p_x;
}
void point::sety(int y) // 设置点的纵坐标y
{
p_y = y;
}
int point::gety()
{
return p_y;
}
注意:在各个头文件中原来的各个函数都是全局函数,但每个函数都是成员函数,因此要加上它自己作用域下的函数point::/circle::
圆类:头文件:circle.h
class circle // 设置 圆 类
{
public:
void setr(int r); // 设置半径
int getr();
void setCenter(point center); // 设置圆心,本质也是个半径
point getCenter();
private:
int c_r;
point c_center;// 一个类中可以包含另一个类,作为原来类的成员
};
源文件:circle.cpp
void circle::setr(int r) // 设置半径
{
c_r = r;
}
int circle::getr()
{
return c_r;
}
void circle::setCenter(point center) // 设置圆心,本质也是个半径
{
c_center = center;
}
point circle::getCenter()
{
return c_center;
}
计算距离、半径平方以及判断
void IsInCircle(circle &c,point &p) // 判断两点之间关系
{
// 计算两点之间距离
int distance=
(c.getCenter().getx() - p.getx()) * (c.getCenter().getx() - p.getx()) +
(c.getCenter().gety() - p.gety()) * (c.getCenter().gety() - p.gety());
// 计算半径的平方
int square = c.getr() * c.getr();
// 判断距离和平方的关系
if (distance == square)
cout << "在圆上" << endl;
else if (distance > square)
cout << "在圆外" << endl;
else
cout << "在圆内" << endl;
}
main
函数
int main()
{
// 创建圆
circle c;
c.setr(1);
point center;
center.setx(2);
center.sety(2);
c.setCenter(center);
// 创建点
point p;
p.setx(2);
p.sety(1);
IsInCircle(c, p);
return 0;
}