C++第5章 类与对象
5.1 类与对象的概念
1. 编程思想:面向过程侧重步骤,面向对象将数据+操作封装为类,核心三大特性:封装、继承、多态。
2. 类的定义:使用 class ,包含数据成员(属性)、成员函数(行为)。
3. 对象:类的实例, 类名 对象名 创建栈对象; new 类名 创建堆对象。访问成员:普通对象用 . ,对象指针用 -> 。
4. 三种存取控制权限
- public 公有:任意位置均可访问;
- private 私有:仅类内部访问,class默认权限;
- protected 保护:类内、派生类可以访问。
5.2 构造函数、析构函数、拷贝构造函数
1. 构造函数:和类同名、无返回值,创建对象自动调用,用于初始化成员。
2. 析构函数: ~类名() ,对象销毁时自动调用,释放堆资源,一个类只能有1个析构。
3. 拷贝构造函数:用已有对象初始化新对象;区分浅拷贝、深拷贝
- 浅拷贝:直接复制地址,多个对象共用堆内存,析构重复释放内存报错;
- 深拷贝:手动开辟独立堆内存,避免内存错误。
5.3 对象的各类使用形式
1. 对象指针: 类名* p = &obj ,配合 -> 访问成员;
2. 对象引用: 类名 &r = obj ,对象别名,作为函数参数减少拷贝;
3. 对象数组:批量创建多个同类对象;动态对象依靠 new/delete 管理堆内存;
4. this 指针:成员函数隐含参数,指向当前调用函数的对象;
5. 组合对象:类内包含其他类作为成员;构造顺序:先成员、再自身,析构顺序相反。
5.4 静态成员 static
1. 静态数据成员:属于整个类,所有对象共享同一份,需要在类外初始化;
2. 静态成员函数:无 this 指针,只能访问静态成员,可直接 类名::函数名() 调用。
5.5 友元(打破封装,访问私有成员)
1. 友元函数:类内声明 friend 外部函数,该函数能读取类私有成员;
2. 友元类:指定另一个类全部函数可访问本类私有;
特性:单向生效、不传递、不继承。
5.6 const 常对象与常成员
1. 常对象 const 类名 obj :对象所有成员禁止修改,仅能调用常成员函数;
2. 常数据成员:只能在构造函数初始化列表赋值,全程不可修改;
3. 常成员函数:函数末尾加 const ,函数内不修改任何成员变量。
5.7 对象的内存分布与释放
1. 内存分配:只有普通成员变量占用对象内存;成员函数、静态成员全局共享,不占用单个对象空间;
2. 内存释放:栈对象出代码块自动调用析构; new 创建的堆对象必须手动 delete 释放,否则造成内存泄漏。
练习题
1.定义一个三角类Ctriangle,求三角形的面积和周长
#include <iostream>
#include <cmath>
using namespace std;
// 题目:定义三角类CTriangle,求三角形的面积(海伦公式)和周长
class CTriangle
{
private:
// 三角形的三条边(私有成员变量)
double a, b, c;
public:
// 构造函数:初始化三条边,并检查是否能构成三角形
CTriangle(double x, double y, double z)
{
// 合法性检查:边长>0,且任意两边之和大于第三边
if (x > 0 && y > 0 && z > 0 &&
x + y > z && x + z > y && y + z > x)
{
a = x;
b = y;
c = z;
}
else
{
cout << "错误:输入的三条边无法构成有效的三角形!" << endl;
// 为避免后续计算出错,强制退出程序
exit(1);
}
}
// 计算周长的成员函数
double getPerimeter()
{
return a + b + c;
}
// 计算面积的成员函数(海伦公式)
double getArea()
{
double p = getPerimeter() / 2; // 半周长
// 海伦公式:面积 = √[p × (p-a) × (p-b) × (p-c)]
return sqrt(p * (p - a) * (p - b) * (p - c));
}
};
int main()
{
double a, b, c;
cout << "请输入三角形的三条边(用空格隔开):";
cin >> a >> b >> c;
// 创建三角形对象
CTriangle tri(a, b, c);
// 输出结果
cout << "-------------------------" << endl;
cout << "三角形的周长为:" << tri.getPerimeter() << endl;
cout << "三角形的面积为:" << tri.getArea() << endl;
return 0;
}
2.定义成原函数,求两点间的距离(使用构造函数)d
#include<iostream>
#include<cmath>
using namespace std;
class Point{
private:
double x,y;
public:
// 带默认参数的构造函数,初始化坐标点
Point(double x=0,double y=0):x(x),y(y){}
// 成员函数:计算两点的距离
double Distance(const Point &p) const
{
double dx=x-p.x;
double dy=y-p.y;
return sqrt(dx*dx+dy*dy);
}
};
int main()
{
cout<<"2547102070翟艺佳";
double x1,y1,x2,y2;
cout<<"请输入第一个点的坐标:";
cin>>x1>>y1;
if(cin.fail())
{
cout<<"不能输入字符!"<<endl;
return 0;
}
cout<<"请输入第二个点的坐标:";
cin>>x2>>y2;
if(cin.fail())
{
cout<<"不能输入字符!"<<endl;
return 0;
}
// 使用构造函数创建两个点对象
Point p1(x1,y1);
Point p2(x2,y2);
cout<<"两点之间的距离为:"<<p1.Distance(p2)<<endl;
return 0;
}
3.定义一个时钟clock,用run成员函数模拟时钟运行
#include <iostream>
#include <ctime>
#include <windows.h>
using namespace std;
class Clock {
private:
int hour, minute, second;
int alarm_h, alarm_m, alarm_s;
bool alarm_set;
public:
// 构造函数:初始化当前时间和闹钟状态
Clock(int h = 0, int m = 0, int s = 0)
: hour(h), minute(m), second(s), alarm_h(0), alarm_m(0), alarm_s(0), alarm_set(false) {}
// 设置闹钟时间
void SetAlarm(int hour, int minute, int second) {
alarm_h = hour;
alarm_m = minute;
alarm_s = second;
alarm_set = true;
cout << "闹钟已设置为:"
<< (alarm_h < 10 ? "0" : "") << alarm_h << ":"
<< (alarm_m < 10 ? "0" : "") << alarm_m << ":"
<< (alarm_s < 10 ? "0" : "") << alarm_s << endl;
}
// 时间走时(秒+1,自动进位)
void tick() {
second++;
if (second >= 60) {
second = 0;
minute++;
if (minute >= 60) {
minute = 0;
hour++;
if (hour >= 24) {
hour = 0;
}
}
}
}
// 模拟时钟运行
void run() {
while (true) {
system("cls"); // Windows清屏
// 显示学号姓名和当前时间
cout << "上机实验2 - 时钟闹钟程序" << endl;
cout << "学号:2547102070 姓名:翟艺佳" << endl;
cout << "---------------------------" << endl;
cout << "当前时间:"
<< (hour < 10 ? "0" : "") << hour << ":"
<< (minute < 10 ? "0" : "") << minute << ":"
<< (second < 10 ? "0" : "") << second << endl;
// 检查是否到达闹钟时间
if (alarm_set && hour == alarm_h && minute == alarm_m && second == alarm_s) {
cout << "\n🔔 响铃!响铃!响铃!" << endl;
break;
}
tick();
Sleep(1000); // 暂停1秒,模拟真实时间流逝
}
}
};
int main() {
cout << "===== 时钟闹钟程序 =====" << endl;
cout << "学号:2547102070 姓名:翟艺佳" << endl;
cout << "---------------------------" << endl;
Clock myClock(0, 0, 0); // 初始时间设为00:00:00
int h, m, s;
cout << "请设置闹钟时间(时 分 秒):";
cin >> h >> m >> s;
myClock.SetAlarm(h, m, s);
cout << "时钟开始运行..." << endl;
Sleep(1500);
myClock.run();
return 0;
}
4.设计一个学生类,包含学生姓名,学号,课程,成绩等信息,计算平均成绩
#include <iostream>
#include <string>
using namespace std;
class Student {
private:
string stu_id; // 学号
string stu_name; // 姓名
string course[5]; // 课程名数组(最多5门课)
double score[5]; // 成绩数组
int course_num; // 实际课程数量
public:
// 构造函数:只初始化课程数,学号姓名后面再输入
Student() {
course_num = 0; // 初始课程数为0
}
// 1. 输入学号和姓名
void inputBasicInfo() {
cout << "请输入学生学号:";
cin >> stu_id;
cout << "请输入学生姓名:";
cin >> stu_name;
}
// 2. 输入一门课程和成绩
void inputCourse() {
if (course_num >= 5) {
cout << "⚠️ 课程数量已达上限(最多5门),无法继续添加!" << endl;
return;
}
cout << "请输入第" << course_num + 1 << "门课程名称:";
cin >> course[course_num]; // 输入课程名
cout << "请输入该课程成绩:";
cin >> score[course_num]; // 输入成绩
// 简单判断成绩是否合理(0-100)
while (score[course_num] < 0 || score[course_num] > 100) {
cout << "❌ 成绩输入无效,请输入0-100之间的数字:";
cin >> score[course_num];
}
course_num++; // 课程数+1
}
// 3. 计算平均成绩
double getAverage() {
if (course_num == 0) {
cout << "还没有录入任何课程成绩!" << endl;
return 0;
}
double sum = 0;
for (int i = 0; i < course_num; i++) {
sum += score[i];
}
return sum / course_num;
}
// 4. 显示所有信息
void showInfo() {
cout << "\n===== 学生信息汇总 =====" << endl;
cout << "学号:" << stu_id << endl;
cout << "姓名:" << stu_name << endl;
cout << "课程与成绩:" << endl;
for (int i = 0; i < course_num; i++) {
cout << " " << course[i] << ":" << score[i] << " 分" << endl;
}
cout << "-------------------------" << endl;
cout << "平均成绩:" << getAverage() << " 分" << endl;
}
};
// 主函数:控制整个流程
int main() {
// 1. 创建学生对象
Student stu;
// 2. 输入学号和姓名
stu.inputBasicInfo();
// 3. 让用户决定输入几门课(最多5门)
int n;
cout << "\n请输入需要录入的课程数量(最多5门):";
cin >> n;
// 限制输入的课程数在1-5之间
while (n < 1 || n > 5) {
cout << "❌ 输入无效,请输入1-5之间的数字:";
cin >> n;
}
// 4. 循环输入每一门课的信息
for (int i = 0; i < n; i++) {
stu.inputCourse();
}
// 5. 显示所有信息和平均分
stu.showInfo();
return 0;
}
更多推荐
所有评论(0)