11 类和对象
-
C++面向对象的三大特性:封装、继承、多态
-
C++认为万事万物都为对象,对象上有其 属性 和 行为
11.1 封装
11.1.1 封装的意义
(一) 意义1:设计类的时候,将 属性 和 行为 作为一个整体,以表现事物
语法:class 类名{ 访问权限: 属性 / 行为};
举例:
#include<iostream>
using namespace std;
const double PI = 3.14;
// 设计一个“圆”类,求圆的周长
class Circle {
// 访问权限
public:// 公共权限
// 属性
int r;
// 行为
double perimeter() { // 求圆周长的“行为”,用函数表示
return 2 * PI * r; // 类的行为函数中可以直接调用属性变量,无需作形参
}
};
int main() {
// 通过“圆”类,创建具体的“圆”对象
Circle c1;
// 给“圆”对象c1的属性进行赋值
c1.r = 10;
cout << "圆的周长为 " << c1.perimeter() << endl; // 注意VS自动补全时对行为函数不会自动加()
system("pause");
return 0;
}
专业名词:
成员: 类中的属性与行为的统称
属性: 也叫 成员属性 、 成员变量
行为: 也叫 成员函数 、 成员方法
(二) 意义2:类在设计时,可以把属性和行为放在不同的权限下,加以控制
访问权限有以下三种:
1.public 公共权限:成员 在 类内可以访问,类外可以访问
2.protected 保护权限:成员 在 类内可以访问,类外不可以访问;子类可以访问父类中的内容
3.private 私有权限:成员 在 类内可以访问,类外不可以访问;子类不可以访问父类中的内容
11.1.2 struct与class的区别
在C++中 struct 与 class 的 唯一区别 在于:默认的访问权限不同——struct默认公共,class默认私有
11.1.3 成员属性设置为私有
(一)优点1:将所有成员属性设置为私有,可以自己控制读写权限
(二)优点2:对于写权限,我们可以检测数据的有效性
class Student {
private:
string name; // 需要可读可写
string stuNum; // 需要只读
int age; // 需要可读可写 & 在0~150之间有效
public:
/------------------------- 优点1 ------------------------/
void setName(string name_input) { // 姓名的“写”方法
name = name_input;
}
string getName() { // 姓名的“读”方法
return name;
}
string getStuNum() { // 学号的“读”方法
return stuNum;
}
/------------------------- 优点2 ------------------------/
void setAge(int age_input) { // 年龄的“写”方法
if ((age_input < 0) || (age_input > 150)) {
cout << "年龄范围错误" << endl;
return;
}
else
age = age_input;
}
int getAge() { // 年龄的“读”方法
return age;
}
};
这样做的好处在于:把属性读写的权限交还给程序员,将属性设为私有后,只有拥有对应的读写方法函数才能对其进行访问修改
实例:设计Circle类与Point类实现对点与圆位置关系的确定
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
/************************* Circle类 **************************/
class Circle {
private:
float centerX, centerY, radius;
public:
void setCenter(float x, float y) { // 设置圆心坐标
centerX = x;
centerY = y;
}
float getCenterX() { // 获取圆心x坐标
return centerX;
}
float getCenterY() { // 获取圆心y坐标
return centerY;
}
void setR(float r) { // 设置半径
radius = r;
}
float getR() { // 获取半径
return radius;
}
};
/************************* Point类 **************************/
class Point {
private:
float X, Y;
public:
void setXY(float x, float y) { // 设置点的坐标
X = x;
Y = y;
}
float getX() { // 获取点的x坐标
return X;
}
float getY() { // 获取点的y坐标
return Y;
}
float distance(float otherX, float otherY) { // 获取其他点与自身的距离
return (float)sqrt(pow(X-otherX,2)+pow(Y-otherY,2));
}
};
int main() {
float circleX, circleY, circleR, pointX, pointY;
Circle circle;
Point point;
cout << "请输入圆心x坐标:";
cin >> circleX;
cout << "请输入圆心y坐标:";
cin >> circleY;
circle.setCenter(circleX, circleY);
cout << "请输入圆的半径:";
cin >> circleR;
while (circleR <= 0) {
cout << "圆的半径必须为正数,请重新输入:";
cin >> circleR;
}
circle.setR(circleR);
cout << "请输入点的x坐标:";
cin >> pointX;
cout << "请输入点的y坐标:";
cin >> pointY;
point.setXY(pointX, pointY);
if (point.distance(circle.getCenterX(), circle.getCenterY()) == circle.getR()) {
cout << "点在圆上" << endl;
}
else if (point.distance(circle.getCenterX(), circle.getCenterY()) < circle.getR()) {
cout << "点在圆内" << endl;
}
else {
cout << "点在圆外" << endl;
}
system("pause");
return 0;
}
重点:对类的分文件编写(以上述代码中的Point类为例)
头文件point.h:放置Point类的声明
-
引用所需的头文件,如iostream
-
删去成员函数的实现内容,以分号收尾
#pragma once // 防止头文件重复包含 #include<iostream> #include<string> using namespace std; class Point { private: float X, Y; public: void setXY(float x, float y); float getX(); float getY(); float distance(float otherX, float otherY); };
源文件point.cpp:放置Point类的实现
-
调用对应的头文件
point.h,注意使用双引号来调用自定义文件 -
仅保留类中的成员函数
-
在每个成员函数前添加
Point::,表示该函数为Point类作用域下的成员函数 -
使用“shift+Tab”键进行自动缩进
#include "point.h" void Point::setXY(float x, float y) { X = x; Y = y; } float Point::getX() { return X; } float Point::getY() { return Y; } float Point::distance(float otherX, float otherY) { return (float)sqrt(pow(X - otherX, 2) + pow(Y - otherY, 2)); }
注意:调用头文件使用 “” 还是 <>
- 尖括号 < >:这种形式告诉编译器在标准系统目录下查找头文件。通常,这些头文件是编译器提供的标准库或者是系统库,,如
#include <iostream> - 引号 " ":这种形式告诉编译器在用户自定义目录或当前目录下查找头文件。通常,这些头文件是用户自己编写的或者是来自项目中的其他源文件,如
#include "point.h"

被折叠的 条评论
为什么被折叠?



