《面向对象程序设计》上机范围打印
考了两个类型转换的题,一共20分
一、
工程实践题:三维空间物体质量与重量计算系统
工程背景:在物流运输、机械设计或材料采购中,经常需要计算不同形状物体的质量(用于运费估算)和重量(用于结构承载计算)。请设计一个面向对象的 C++ 程序,使用抽象基类作为接口,计算不同三维物体的质量和重量(重力 = 质量 × g)。
具体要求:
- 抽象基类 SolidObject 设计:
纯虚函数 volume():计算物体体积
纯虚函数 mass(double density):计算物体质量(质量 = 密度 × 体积)
纯虚函数 weight(double density, double g):计算物体重量(重量 = 质量 × 重力加速度)
纯虚函数 printType():输出物体类型名称 - 派生具体类(至少实现 3 个):
Box(长方体):数据成员为长(length)、宽(width)、高(height)
Ball(球体):数据成员为半径(radius)
Cylinder(圆柱体):数据成员为底面半径(radius)和高(height) - 工程实践要求:
使用 const 修饰不修改成员变量的成员函数
使用 初始化列表 进行构造函数初始化
编写一个 全局打印函数 printObjectInfo(const SolidObject* pObj, double density, double g),通过基类指针访问派生类对象,输出:物体类型、体积、质量、重量 - 计算公式提示:
长方体体积:length × width × height
球体体积:(4/3) × π × radius³
圆柱体体积:π × radius² × height
质量 = 密度 × 体积
重量 = 质量 × 重力加速度 g
//5.28
#include <iostream>
using namespace std; // 修复1:引入命名空间
// 抽象基类
class SolidObject {
public:
virtual ~SolidObject() {}
virtual double volume() const = 0;
// 修复5:严格按照题目要求,声明为纯虚函数
virtual double mass(double density) const = 0;
virtual double weight(double density, double g) const = 0;
virtual void printType() const = 0;
};
// 派生类:长方体
class Box : public SolidObject {
private:
double length, width, height;
public:
Box(double l, double w, double h) : length(l), width(w), height(h) {}
double volume() const override { return length * width * height; }
// 实现基类的纯虚函数
double mass(double density) const override { return volume() * density; }
double weight(double density, double g) const override { return mass(density) * g; }
void printType() const override { cout << "Box"; }
};
// 派生类:球体
class Ball : public SolidObject {
private:
double radius;
public:
Ball(double r) : radius(r) {}
// 修复3:体积公式修改为 r 的三次方
double volume() const override { return (4.0 / 3.0) * 3.14 * radius * radius * radius; }
double mass(double density) const override { return volume() * density; }
double weight(double density, double g) const override { return mass(density) * g; }
void printType() const override { cout << "Ball"; }
};
// 派生类:圆柱体
class Cylinder : public SolidObject {
private:
double radius, height;
public:
// 修复2:构造函数名改为 Cylinder,修正参数 h
Cylinder(double r, double h) : radius(r), height(h) {}
double volume() const override { return 3.14 * radius * radius * height; }
double mass(double density) const override { return volume() * density; }
double weight(double density, double g) const override { return mass(density) * g; }
void printType() const override { cout << "Cylinder"; }
};
// 全局打印函数
void printObjectInfo(const SolidObject* p, double density, double g) {
p->printType();
cout << endl;
cout << "volume: " << p->volume() << endl;
cout << "mass: " << p->mass(density) << endl;
// 修复4:传入 density 和 g
cout << "weight: " << p->weight(density, g) << endl;
cout << "----------------------" << endl;
}
// 简单的 main 函数用于测试
int main() {
Box box(2.0, 3.0, 4.0);
Ball ball(2.0);
Cylinder cylinder(2.0, 5.0);
double ironDensity = 7850.0; // 铁的密度 kg/m³
double g = 9.8; // 重力加速度
printObjectInfo(&box, ironDensity, g);
printObjectInfo(&ball, ironDensity, g);
printObjectInfo(&cylinder, ironDensity, g);
return 0;
}
二、
工程实践题:二维平面图形周长与面积计算系统
工程背景:在CAD绘图、土地测量、建筑设计或包装材料裁剪中,经常需要计算不同二维图形的周长(材料边框长度)和面积(材料用量)。请设计一个面向对象的C++程序,使用抽象基类作为接口,计算不同二维图形的周长和面积。
具体要求:
- 抽象基类 Shape2D 设计:
纯虚函数 perimeter():计算图形周长
纯虚函数 area():计算图形面积
纯虚函数 printType():输出图形类型名称 - 派生具体类(至少实现 3 个):
Rectangle(矩形):数据成员为长度(length)和宽度(width)
Circle(圆形):数据成员为半径(radius)
Triangle(等边三角形):数据成员为边长(side) - 工程实践要求:
使用 const 修饰不修改成员变量的成员函数
使用 初始化列表 进行构造函数初始化
编写一个 全局打印函数 printShapeInfo(Shape2D* pShape),通过基类指针访问派生类对象,输出:图形类型、周长、面积 - 计算公式提示:
矩形周长:2 × (length + width),面积:length × width
圆形周长:2 × π × radius,面积:π × radius²(π 取 3.14159)
等边三角形周长:3 × side,面积:(√3 / 4) × side²(√3 取 1.732)
//5.28
#include <iostream>
using namespace std;
class Shape2D {
public:
// 最佳实践:为多态基类添加虚析构函数
virtual ~Shape2D() {}
virtual double perimeter() const = 0;
virtual double area() const = 0;
virtual void printType() const = 0;
};
class Rectangle : public Shape2D {
private:
double length, width;
public:
Rectangle(double length = 0, double width = 0) : length(length), width(width) {}
double perimeter() const override { return 2 * (length + width); }
double area() const override { return length * width; }
// 修复:添加 const override 以精确匹配基类
void printType() const override { cout << "Rectangle" << endl; }
};
class Circle : public Shape2D {
private:
double radius;
public:
// 修复:添加漏掉的冒号 :
Circle(double r = 0) : radius(r) {}
double perimeter() const override { return 2 * 3.14 * radius; }
double area() const override { return 3.14 * radius * radius; }
// 修复:添加 const override
void printType() const override { cout << "Circle" << endl; }
};
class Triangle : public Shape2D {
private:
double side;
public:
// 修复:添加漏掉的冒号 :
Triangle(double s = 0) : side(s) {}
double perimeter() const override { return 3 * side; }
double area() const override { return (1.732 / 4.0) * side * side; }
// 修复:添加 const override
void printType() const override { cout << "Triangle" << endl; }
};
void printShapeInfo(const Shape2D* p) { // 建议传入 const 指针保护数据
p->printType();
cout << "perimeter: " << p->perimeter() << endl;
cout << "area: " << p->area() << endl;
cout << "-----------------" << endl;
}
三、
设计一个 ElectricField2D 类(二维电场强度类)
用于模拟二维平面中多个点电荷产生的电场强度矢量(Ex, Ey),支持电场的合成(矢量相加)与差分计算。
//在某一个位置的Ex,Ey,正电荷,由场源电荷指向目标点,然后再分解ExEy
私有成员:
ex:x 方向的电场强度(double 类型)
ey:y 方向的电场强度(double 类型)
友元函数(重载运算符):
friend istream& operator>>(istream&, ElectricField2D&)
重载输入运算符 >>,能够直接输入电场强度的 Ex、Ey 分量
格式:Ex Ey(两个数字用空格或回车分隔)
friend ostream& operator<<(ostream&, const ElectricField2D&)
重载输出运算符 <<,能够直接输出电场强度矢量
格式:(Ex, Ey),保留两位小数
friend ElectricField2D operator+(const ElectricField2D&, const ElectricField2D&)
重载加法运算符 +,实现两个电场强度的合成(矢量相加)
friend ElectricField2D operator-(const ElectricField2D&, const ElectricField2D&)
重载减法运算符 -,计算两个电场强度的矢量差
额外要求(工程实践):
添加一个成员函数 double magnitude(),计算电场强度的大小(场强模),公式:sqrt(Ex² + Ey²)
可选:
构造函数 ElectricField2D(double exVal = 0, double eyVal = 0)
# 三、
设计一个 ElectricField2D 类(二维电场强度类)
用于模拟二维平面中多个点电荷产生的电场强度矢量(Ex, Ey),支持电场的合成(矢量相加)与差分计算。
//在某一个位置的Ex,Ey,正电荷,由场源电荷指向目标点,然后再分解ExEy
私有成员:
ex:x 方向的电场强度(double 类型)
ey:y 方向的电场强度(double 类型)
友元函数(重载运算符):
friend istream& operator>>(istream&, ElectricField2D&)
重载输入运算符 >>,能够直接输入电场强度的 Ex、Ey 分量
格式:Ex Ey(两个数字用空格或回车分隔)
friend ostream& operator<<(ostream&, const ElectricField2D&)
重载输出运算符 <<,能够直接输出电场强度矢量
格式:(Ex, Ey),保留两位小数
friend ElectricField2D operator+(const ElectricField2D&, const ElectricField2D&)
重载加法运算符 +,实现两个电场强度的合成(矢量相加)
friend ElectricField2D operator-(const ElectricField2D&, const ElectricField2D&)
重载减法运算符 -,计算两个电场强度的矢量差
额外要求(工程实践):
添加一个成员函数 double magnitude(),计算电场强度的大小(场强模),公式:sqrt(Ex² + Ey²)
可选:
构造函数 ElectricField2D(double exVal = 0, double eyVal = 0)
这题+和-时可以直接调用构造函数,直接return 一下就可以了
class ElectricField2D {
private:
double ex;
double ey;
public:
ElectricField2D(double exVal = 0, double eyVal = 0) : ex(exVal), ey(eyVal) {}
double magnitude() const {
return sqrt(ex * ex + ey * ey);
}
friend istream& operator>>(istream& is, ElectricField2D& field) {
is >> field.ex >> field.ey;
return is;
}
friend ostream& operator<<(ostream& os, const ElectricField2D& field) {
os << fixed << setprecision(2) << "(" << field.ex << ", " << field.ey << ")";
return os;
}
friend ElectricField2D operator+(const ElectricField2D& f1, const ElectricField2D& f2) {
return ElectricField2D(f1.ex + f2.ex, f1.ey + f2.ey);
}
friend ElectricField2D operator-(const ElectricField2D& f1, const ElectricField2D& f2) {
return ElectricField2D(f1.ex - f2.ex, f1.ey - f2.ey);
}
};
```cpp
#include <iostream>
#include <cmath>
#include <iomanip> // 用于保留两位小数 (setprecision)
using namespace std;
// 统一类名为 ElectricField2D (补上了 r)
class ElectricField2D {
private:
double ex, ey;
public:
// 构造函数
ElectricField2D(double exVal = 0, double eyVal = 0) : ex(exVal), ey(eyVal) {}
// 计算模长,修正了 sqrt 参数,并加上 const
double magnitude() const {
return sqrt(ex * ex + ey * ey);
}
// 友元函数声明
friend istream &operator>>(istream &, ElectricField2D &);
friend ostream &operator<<(ostream &, const ElectricField2D &);
friend ElectricField2D operator+(const ElectricField2D &, const ElectricField2D &);
friend ElectricField2D operator-(const ElectricField2D &, const ElectricField2D &);
};
// 重载输入运算符 >>
istream &operator>>(istream &is, ElectricField2D &obj) {
is >> obj.ex >> obj.ey;
return is;
}
// 重载输出运算符 <<
ostream &operator<<(ostream &os, const ElectricField2D &obj) {
// 修复:去掉分号、修正 boj、添加保留两位小数控制、返回 os
os << "(" << fixed << setprecision(2) << obj.ex << ", " << obj.ey << ")";
return os;
}
// 重载加法运算符 +
ElectricField2D operator+(const ElectricField2D &e1, const ElectricField2D &e2) {
ElectricField2D temp;
temp.ex = e1.ex + e2.ex;
temp.ey = e1.ey + e2.ey;
return temp;
}
// 重载减法运算符 - (修复:之前错写成了 operator+)
ElectricField2D operator-(const ElectricField2D &e1, const ElectricField2D &e2) {
ElectricField2D temp;
temp.ex = e1.ex - e2.ex;
temp.ey = e1.ey - e2.ey;
return temp;
}
// 你可以在本地加一个 main 函数来测试它:
/*
int main() {
ElectricField2D e1, e2;
cout << "请输入第一个电场 (Ex Ey): ";
cin >> e1;
cout << "请输入第二个电场 (Ex Ey): ";
cin >> e2;
cout << "e1: " << e1 << " 模长: " << e1.magnitude() << endl;
cout << "e2: " << e2 << " 模长: " << e2.magnitude() << endl;
cout << "e1 + e2 = " << (e1 + e2) << endl;
cout << "e1 - e2 = " << (e1 - e2) << endl;
return 0;
}
*/
//5.28
#include <iostream>
#include <cmath>
#include <iomanip>
using namespace std;
class ElectricField2D{
private:
double ex,ey;
public:
ElectricField2D(double exVal=0,double eyVal=0):ex(exVal),ey(eyVal){ }
friend istream& operator>>(istream &is,ElectricField2D &obj){
is>>obj.ex>>obj.ey;
return is;
}
friend ostream& operator<<(ostream &os,const ElectricField2D &obj){
os<<fixed<<setprecision(2);
os<<"("<<obj.ex<<","<<obj.ey<<")";
return os;
}
friend ElectricField2D operator+(const ElectricField2D &obj1,const ElectricField2D &obj2){
ElectricField2D temp;
temp.ex=obj1.ex+obj2.ex;
temp.ey=obj1.ey+obj2.ey;
return temp;
}
friend ElectricField2D operator-(const ElectricField2D &obj1,const ElectricField2D &obj2){
ElectricField2D temp;
temp.ex=obj1.ex-obj2.ex;
temp.ey=obj1.ey-obj2.ey;
return temp;
}
double magnitude(){
return sqrt(ex*ex+ey*ey);
}
};
四、
设计一个 FloatStack 类(浮点型栈类)
用于模拟一个动态栈(基于数组实现),支持入栈和自动扩容。
私有成员:
data:动态分配的 float 数组(存储栈元素)
top:栈顶指针(当前元素个数,等同于原 size)
capacity:栈的容量
公有成员函数:
构造函数 FloatStack(int initCap = 10)
初始化栈,容量为 initCap,栈顶为0,动态分配数组
析构函数 ~FloatStack()
释放动态内存
拷贝构造函数 FloatStack(const FloatStack& other)
实现深拷贝
重载赋值运算符 operator=(const FloatStack& other)
实现深拷贝并处理自赋值
void push(float val)
入栈(在末尾添加元素)
如果栈满(top >= capacity),自动扩容为原来的 1.5 倍
void display()
输出所有元素,格式:Stack: [1.1, 2.2, 3.3]
int getSize()
返回栈中元素个数
//5.30
#include <iostream>
#include <iomanip>
using namespace std;
class FloatStack{
private:
float*data;
int top;
int capacity;
public:
FloatStack(int initCap=10){
capacity=(initCap>0)?initCap:1;
top=0;
data=new float[capacity];
}
//FloatStack s1=s2;
//FloatStack s1;
//s1=s2; //=
FloatStack(const FloatStack&other){
capacity=other.capacity;
data=new float[capacity];
top=other.top;
for(int i = 0;i<top;i++){
this->data[i]=other.data[i];
}
}
~FloatStack(){
delete []data;
}
FloatStack& operator=(const FloatStack&other)
//s1=s2=s3
{ if (this != &other) {
// 先分配新内存并拷贝,防止 new 失败导致原对象被破坏
float* newData = new float[other.capacity];
for (int i = 0; i < other.top; ++i) {
newData[i] = other.data[i];
}
// 再释放旧内存并更新成员
delete[] data;
data = newData;
capacity = other.capacity;
top = other.top;
}
return *this;
}
void push(float val){
if(top>=capacity){
int newCapacity=capacity*1.5;
if(newCapacity<=capacity){
newCapacity=capacity+1;
}
//1,1.5->1
float *newData=new float[newCapacity];
for(int i=0;i<top;++i){
newData[i]=data[i];
}
delete []data;// memory leak
capacity=newCapacity;
data = newData;
}
data[top++]=val;
}
float pop(){
if(top==0){
cout<<"stack empty!"<<endl;
return 0.0;
}
else{
return data[--top];
}
}
int getSize()const {
return top;
}
void display()const {
cout<<"Stack:[";
if(top>0){
cout<<fixed<<setprecision(2);
for(int i=0;i<top-1;i++){
cout<<data[i]<<", ";
}
cout<<data[top-1];
}
cout<<"]"<<endl;
}
};
五、
设计一个 FixedDeposit 类(定期存款单类)
用于模拟银行定期存款管理。
私有成员:
certificateId(存单ID,int 类型,自动生成)
depositor(存款人姓名,string 类型)
bankName(银行名称,string 类型)
amount(存款金额,double 类型,必须 ≥ 0)
status(存单状态,string 类型,只能是 "ACTIVE"、"MATURED"、"CANCELLED")
公有成员函数:
构造函数 FixedDeposit(string name, string bank, double amt)//初始化存款人、银行名称和金额。
存单ID 使用静态成员自动递增生成(从 2001 开始)
状态初始为 "ACTIVE"
如果金额 < 0,则设为 0 并打印警告:"Warning: Invalid amount set to 0"
bool mature(int currentMonth, int depositMonths)
模拟到期处理:
检查当前月份 currentMonth 是否 ≥ 存入月份 + 存期 depositMonths
如果是 → 状态改为 "MATURED",返回 true
如果否 → 状态改为 "CANCELLED"(提前支取),返回 false
void display()
输出格式:
[ID:2001] 5000.00 from 张三 at ICBC → ACTIVE
string getStatus()
返回存单状态
double getAmount()
返回存款金额(只读)
//5.28
#include <iostream>
#include <string>
#include <iomanip> // 修复1:正确的头文件拼写
using namespace std;
class FixedDeposit {
private:
static int nextId; // 修复3:统一静态变量的大小写
int certificateID;
string depositor;
string bankName;
double amount;
int month;
string status;
public:
FixedDeposit(string name, string bank, double amt, int m) : depositor(name), bankName(bank), month(m) {
if (amt < 0) {
cout << "Warning: Invalid amount set to 0" << endl;
amount = 0; // 修复2:修正 amount 拼写
} else {
amount = amt;
}
status = "ACTIVE";
certificateID = nextId++; // 修复3:统一使用 nextId
}
bool mature(int currentMonth, int depositMonths) {
// 修复4:严格按照题目公式:当前月份 >= 存入月份 + 存期
if (currentMonth >= month + depositMonths) {
status = "MATURED";
return true;
} else {
status = "CANCELLED";
return false;
}
}
void display() {
// 修复5:补上右侧括号 ],并在 at 前面加上空格
cout << "[ID:" << certificateID << "] " << fixed << setprecision(2) << amount
<< " from " << depositor << " at " << bankName << " -> " << status << endl;
}
string getStatus() {
return status;
}
double getAmount() const {
return amount;
}
};
// 修复3:在类外初始化静态变量时,去掉 static 关键字,且保持名称大小写一致
int FixedDeposit::nextId = 2001;
六、
题目:设计一个 ProductPrice 类
用于管理一个商品的价格并给出价格等级。
私有成员:
productName(商品名称,string 类型)
price(价格,float 类型,范围 0–1000 元)
公有成员函数:
setInfo(string name, float p)
设置商品名称和价格。
要求:如果价格 < 0,则设为 0;如果价格 > 1000,则设为 1000。
char getLevel()
根据价格返回等级(越便宜等级越高):
0–200 → 非常便宜
201–400 →较便宜
401–600 → 中等
601–800 →较贵
801–1000 → 很贵
bool isCheap()
返回是否便宜(价格 ≤ 400 元)。
void display()
输出格式:
Product: 华为手机, Price: 350.0, Level: B, Cheap: YES
float getPrice()
返回价格(只读)
//5.28
#include <iostream>
#include <string>
#include <iomanip> // 修复5:必须包含这个头文件才能用 setprecision
using namespace std;
class ProductPrice {
private:
float price;
string productName;
public:
// 1. 设置信息
void setInfo(string name, float p) {
productName = name;
if (p < 0) {
price = 0;
} else if (p > 1000) {
price = 1000;
} else {
price = p;
}
}
// 2. 获取等级 (修复1:使用单引号 'A';修复2:补全5个等级)
char getLevel() {
if (price >= 0 && price <= 200) {
return 'A';
} else if (price >= 201 && price <= 400) {
return 'B';
} else if (price >= 401 && price <= 600) {
return 'C';
} else if (price >= 601 && price <= 800) {
return 'D';
} else {
return 'E';
}
}
// 3. 判断是否便宜
bool isCheap() {
// 【优雅写法】:因为 price <= 400 本身就是一个会计算出 true 或 false 的布尔表达式
// 所以不需要写 if...return true else return false,直接 return 即可。
return price <= 400;
}
// 4. 显示信息 (修复3:删除了非法文本;修复4:补齐了 getLevel 的输出)
void display() {
cout << "Product: " << productName
<< ", Price: " << fixed << setprecision(2) << price
<< ", Level: " << getLevel()
<< ", Cheap: ";
if (isCheap()) {
cout << "YES" << endl;
} else {
cout << "NO" << endl;
}
}
// 5. 获取价格 (修复6:补上题目遗漏的函数)
float getPrice() {
return price;
}
};
七、阅读程序写结果
include
using namespace std;
class Score
{
private:
int point;
public:
Score(int p = 60) : point(p)
{
cout << "creating score " << point << endl;
}
operator int() const
{
cout << "score convert" << endl;
return point;
}
};
int main()
{
Score s = 95;
cout << s << endl;
return 0;
}
八、阅读程序写结果
include
using namespace std;
class Vector3D
{
private:
double x;
double y;
double z;
public:
Vector3D()
{
x = 0; y = 0; z = 0;
cout << "constructing (" << x << "," << y << "," << z << ")" << endl;
}
Vector3D(double a, double b, double c)
{
x = a; y = b; z = c;
cout << "constructing (" << x << "," << y << "," << z << ")" << endl;
}
operator double()
{
cout << "type changing" << endl;
return x;
}
};
int main()
{
Vector3D v1(3, 4, 5), v2(7, -2, 1), v3;
double result;
result = 1.5 + v1;
cout << result << endl;
return 0;
}
九、阅读程序写结果
include
using namespace std;
class Point
{
private:
int x;
int y;
public:
Point(int a = 0, int b = 0) : x(a), y(b)
{
cout << "constructing (" << x << "," << y << ")" << endl;
}
operator int() const
{
cout << "type changing" << endl;
return x + y;
}
};
int main()
{
Point p = 8;
cout << p << endl;
return 0;
}
十、阅读程序写结果
include
using namespace std;
class Vector2D
{
private:
double x;
double y;
public:
Vector2D()
{
x = 0; y = 0;
cout << "constructing (" << x << "," << y << ")" << endl;
}
Vector2D(double a, double b)
{
x = a; y = b;
cout << "constructing (" << x << "," << y << ")" << endl;
}
operator double()
{
cout << "type changing" << endl;
return x;
}
};
int main()
{
Vector2D v1(3, 4), v2(5, -10), v3;
double d;
d = 2.5 + v1;
cout << d << endl;
return 0;
}
浙公网安备 33010602011771号