《面向对象程序设计》上机范围打印

考了两个类型转换的题,一共20分

一、

工程实践题:三维空间物体质量与重量计算系统
工程背景:在物流运输、机械设计或材料采购中,经常需要计算不同形状物体的质量(用于运费估算)和重量(用于结构承载计算)。请设计一个面向对象的 C++ 程序,使用抽象基类作为接口,计算不同三维物体的质量和重量(重力 = 质量 × g)。
具体要求:

  1. 抽象基类 SolidObject 设计:
    纯虚函数 volume():计算物体体积
    纯虚函数 mass(double density):计算物体质量(质量 = 密度 × 体积)
    纯虚函数 weight(double density, double g):计算物体重量(重量 = 质量 × 重力加速度)
    纯虚函数 printType():输出物体类型名称
  2. 派生具体类(至少实现 3 个):
    Box(长方体):数据成员为长(length)、宽(width)、高(height)
    Ball(球体):数据成员为半径(radius)
    Cylinder(圆柱体):数据成员为底面半径(radius)和高(height)
  3. 工程实践要求:
    使用 const 修饰不修改成员变量的成员函数
    使用 初始化列表 进行构造函数初始化
    编写一个 全局打印函数 printObjectInfo(const SolidObject* pObj, double density, double g),通过基类指针访问派生类对象,输出:物体类型、体积、质量、重量
  4. 计算公式提示:
    长方体体积: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++程序,使用抽象基类作为接口,计算不同二维图形的周长和面积。
具体要求:

  1. 抽象基类 Shape2D 设计:
    纯虚函数 perimeter():计算图形周长
    纯虚函数 area():计算图形面积
    纯虚函数 printType():输出图形类型名称
  2. 派生具体类(至少实现 3 个):
    Rectangle(矩形):数据成员为长度(length)和宽度(width)
    Circle(圆形):数据成员为半径(radius)
    Triangle(等边三角形):数据成员为边长(side)
  3. 工程实践要求:
    使用 const 修饰不修改成员变量的成员函数
    使用 初始化列表 进行构造函数初始化
    编写一个 全局打印函数 printShapeInfo(Shape2D* pShape),通过基类指针访问派生类对象,输出:图形类型、周长、面积
  4. 计算公式提示:
    矩形周长: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;
}

posted @ 2026-06-03 12:07  叶臧  阅读(16)  评论(0)    收藏  举报