第十一章 类和对象——第1节 封装

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"
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值