《面向对象程序设计》上机范围
考了两个类型转换的题,一共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;
}
#include <iostream>
using namespace std;
//同个类,同名不同参 = 重载
//父子类,虚函数完全一致 = 重写
//纯虚函数子类实现 = 重写
class SolidObject{
public:
virtual ~SolidObject(){ }
virtual double volume() const = 0;
//mass 和 weight不用纯虚函数,题目要求纯的话,那就按题目来吧
//纯虚函数派生子类必须重写
// 如果只是虚函数,那么派生类会动态继承这两个虚函数
// virtual double mass(double density)const = 0;
// C++ 确实允许纯虚函数有实现体,但绝对不能在类定义里面把 = 0 和 { ... } 连在一起写。
// {
//
// double v1=volume;
//
// return density*v1;
// }
//如果是虚函数则必须要有函数体
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 length,double width,double height):length(length),width(width),height(height){
}
double volume()const override{
return length*width*height;
}
double mass(double density) const override{
double v1=volume();
return density*v1;
}
double weight(double density,double g) const override{
double m1=mass(density);
return m1*g;
}
void printType() const {
cout<<"Box"<<endl;
}
};
class Ball:public SolidObject{
private:
double radius;
public:
Ball(double r):radius(r){
}
double volume()const override{
// return (4/3)*3.14*radius*radius*radius;
return (4.0/3.0)*3.14*radius*radius*radius;
}
double mass(double density) const override{
double v1=volume();
return density*v1;
}
double weight(double density,double g) const override{
double m1=mass(density);
return m1*g;
}
void printType() const {
cout<<"Ball"<<endl;
}
};
class Cylinder:public SolidObject{
private:
double radius,height;
public:
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{
double v1=volume();
return density*v1;
}
double weight(double density,double g) const override{
double m1=mass(density);
return m1*g;
}
void printType() const {
cout<<"Cylinder"<<endl;
}
};
void printObjectInfo(const SolidObject * pObj,double density , double g){
pObj->printType();
cout<<pObj->volume()<<endl;
cout<<pObj->mass(density)<<endl;
cout<<pObj->weight(density,g)<<endl;
}
int main() {
double density, g;
double length, width, height;
double ball_radius;
double cyl_radius, cyl_height;
cin >> density >> g;
cin >> length >> width >> height;
cin >> ball_radius;
cin >> cyl_radius >> cyl_height;
SolidObject* b1 = new Box(length, width, height);
SolidObject* b2 = new Ball(ball_radius);
SolidObject* c1 = new Cylinder(cyl_radius, cyl_height);
printObjectInfo(b1, density, g);
printObjectInfo(b2, density, g);
printObjectInfo(c1, density, g);
delete b1;
delete b2;
delete c1;
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;
}
#include <iostream>
using namespace std;
class Shape2D{
public:
virtual double perimeter() const =0;
//纯虚函数 类中不能有{}
virtual double area()const =0;
virtual void printType()const =0;
// 新增:虚析构函数,防止基类指针删除派生类对象时内存泄漏
virtual ~Shape2D() = default;
};
//纯虚函数 派生类必须重写
//注意不是重载,参数名字等必须相同
class Rectangle:public Shape2D{
private:
double length,width;
public:
Rectangle(double l,double w):length(l),width(w){
}
double perimeter()const override{
return 2*(length+width);
}
double area()const override{
return length*width;}
void printType()const override{
cout<<"Rectangle"<<endl;
}
};
class Circle:public Shape2D{
private:
double radius;
public:
Circle(double r):radius(r){
}
double perimeter()const override{
return 2*3.14159*radius; // 修正:按题目要求π取3.14159
}
double area()const override{
return 3.14159*radius*radius;} // 修正:按题目要求π取3.14159
void printType()const override{
cout<<"Circle"<<endl;
}
};
class Triangle:public Shape2D{
private:
double side;
public:
Triangle(double side):side(side){ // 修正:构造函数名必须与类名一致
}
double perimeter()const override{
return 3*side;
}
double area()const override{
return (1.732/4.0)*side*side;}
void printType()const override{
cout<<"Triangle"<<endl;
}
};
void printShapeInfo(Shape2D * pShape){ // 修正:按题目要求函数名为printShapeInfo
pShape->printType();
cout<<"perimeter:"<<pShape->perimeter()<<endl;
cout<<"area:"<<pShape->area()<<endl;
}
int main(){
int l1,w1;
cin>>l1>>w1;
Rectangle *r1 = new Rectangle(l1,w1);
int r; // 修正:变量名不能重复,原来的r1已经被定义为指针
cin>>r;
Circle *c1 = new Circle(r); // 修正:使用新的变量名r
int side;
cin>>side;
Triangle *t1 = new Triangle(side); // 修正:类名拼写错误,少了一个l
printShapeInfo(r1);
printShapeInfo(c1);
printShapeInfo(t1);
delete r1;
delete c1;
delete t1;
return 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)
#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
//设计一个 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()
//返回栈中元素个数
#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){
delete []data;
capacity=other.capacity;
top=other.top;
data=new float[capacity];
for(int i =0;i<top;++i){
data[i]=other.data[i];
}
}
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(){
return top;
}
void display(){
cout<<"Stack:[";
if(top>0){
for(int i=0;i<top-1;i++){
cout<<fixed<<setprecision(2)<<data[i]<<",";
}
cout<<data[top-1];
}
cout<<"]"<<endl;
}
};
int main(){
FloatStack s1;
s1.push(3);
s1.push(2);
s1.push(1);
s1.display();
FloatStack s2;
s2.display();
return 0;
}
//5.29
#include <iostream>
using namespace std;
class FloatStack {
private:
float *data;
int top;
int capacity;
public:
// 1. 构造函数 (修复了参数类型缺失的问题)
FloatStack(int initCap = 10) {
capacity = (initCap > 0) ? initCap : 1;
top = 0;
data = new float[capacity];
}
// 2. 析构函数 (补充:释放动态分配的内存,防止内存泄漏)
~FloatStack() {
delete[] data;
}
// 3. 拷贝构造函数
FloatStack(const FloatStack& other) {
capacity = other.capacity;
top = other.top;
data = new float[capacity];
for (int i = 0; i < top; ++i) {
data[i] = other.data[i];
}
}
// 4. 重载赋值运算符
FloatStack& operator=(const FloatStack& other) {
if (this != &other) {
delete[] data; // 释放原内存
// 赋值应与 other 保持完全一致,无需在这里扩容
capacity = other.capacity;
top = other.top;
data = new float[capacity];
for (int i = 0; i < top; ++i) {
data[i] = other.data[i];
}
}
return *this;
}
// 5. 入栈
void push(float val) {
if (top >= capacity) {
// 扩容为原来的 1.5 倍
int newCapacity = capacity * 1.5;
// 防止 capacity 为 1 时,1 * 1.5 转为 int 依然是 1 的死循环
if (newCapacity <= capacity) {
newCapacity = capacity + 1;
}
// 修复:必须按照 newCapacity 申请内存,而不是旧的 capacity
float *newData = new float[newCapacity];
for (int i = 0; i < top; ++i) {
newData[i] = data[i];
}
delete[] data;
data = newData;
capacity = newCapacity;
}
data[top++] = val;
}
// 出栈 (非题目强制要求,但帮你保留并优化了下)
float pop() {
if (top == 0) {
cout << "栈空" << endl;
return 0.0;
}
return data[--top];
}
// 6. 获取元素个数
int getSize() {
return top;
}
// 7. 输出所有元素
void display() {
// 修复:处理栈为空的情况,防止访问 data[-1]
if (top == 0) {
cout << "Stack: []" << endl;
return;
}
cout << "Stack: [";
for (int i = 0; i < top - 1; ++i) {
cout << data[i] << ", ";
}
cout << data[top - 1] << "]" << endl;
}
};
// 简单的测试代码,方便你验证逻辑
int main() {
FloatStack fs(2); // 初始容量设小一点,方便测试扩容
fs.push(1.1);
fs.push(2.2);
fs.push(3.3); // 此时会触发扩容
fs.display();
cout << "Size: " << fs.getSize() << endl;
FloatStack fs2 = fs; // 测试拷贝构造
fs2.push(4.4);
fs2.display();
FloatStack fs3(5);
fs3 = fs; // 测试赋值运算符
fs3.display();
return 0;
}
#include <iostream>
//栈顶为0->top始终指向栈顶元素的下一个位置,这样,top的小就是栈中元素的个数
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(){
delete [] data;
}
FloatStack(const FloatStack&other){
this->capacity=other.capacity;
top=other.top;
data=new float[this->capacity];
for(int i=0;i<top;++i){
this->data[i]=other.data[i];
}
}
// // 浅拷贝(错误写法)
//FloatStack(const FloatStack & other){
// capacity = other.capacity;
// top = other.top;
// data = other.data; // 直接共用同一块内存!没有new,
//新对象的指针,直接指向原对象数组的起始地址,二者共用同一块堆内存。
//}
//支持连续赋值 和 提高执行效率(避免多余的拷贝)。
//s1=s2=s3
//(s2=s3) 赋值运算符具有右结合性:从右向左开始执行
FloatStack& operator = (const FloatStack & other) {
//自赋值检验
if(this!=&other){
// if(this->capacity==other.capacity){直接覆盖,this->top=other.top;for(int i=0;i<top;++i){this->data[i]=other.data[i];} }
delete [] data;
//因为后面的capacity不一样了,所以索性就释放掉,重新申请
//不进行覆盖
//data 相当于this->data
//如果·不·delete直接new一个,我们不是在原来那块空间申请,而是在其他位置,原来那块空间就成了死空间,内存泄漏(Memory leak)
//现代c++引入了只能指针,即使忘记释放掉,也会帮我们释放掉
this->capacity=other.capacity;
this->top=other.top;
data=new float[this->capacity];
for(int i=0;i<top;++i){
this->data[i]=other.data[i];
}
}
return *this;
}
void push(float val){
//栈满,先扩容,在入栈
if(top>=capacity){
int newCapacity=this->capacity*1.5;
// 处理边界情况:如果原 capacity 是 1,1 * 1.5 强转为 int 后还是 1
//1*1.5=1
if(newCapacity<=capacity){
newCapacity=capacity+1;
}
//避免使用临时数组,直接把数据复制到新数组中,再释放原数组
float *newData=new float[newCapacity];
for(int i=0;i<top;++i){
newData[i]=data[i];
}
delete []data;
data=newData;
//data指向新的数组,本对象的data,后面top也不用考虑
capacity=newCapacity;
}
data[top++]=val;
}
void display()const{
cout<<"Stack:[";
for(int i=top-1;i>=0;--i){
cout<<data[i];
if(i>0){
cout<<",";
}
}
cout<<"]"<<endl;
}
float pop(){
if(this->top==0){
cout<<"栈空"<<endl;
return 0;
}
return data[--top];
}
int getSize()const{
// 普通对象(如你的 s1 和 s2):拥有最高权限。它们既可以调用非 const 的函数(如 push 和 pop,去修改数据),也能调用带有 const 的函数(如 getSize,去读取数据)。
//
//常量对象(如 const FloatStack s3;):权限被严格限制。它们只能调用末尾带有 const 后缀的函数,绝对不允许调用 push 这种可能修改数据的函数。
return top;
}
};
int main(){
FloatStack s1(3);
s1.push(1.1);
s1.push(2.2);
s1.display();
cout<<"元素个数"<<s1.getSize()<<endl;
FloatStack s2=s1;
s2.display();
FloatStack s3;
s3=s1;
return 0;
}
//5.24
#include <iostream>
using namespace std;
class FloatStack{
private:
float*data;
int top;
int capacity;
public:
FloatStack(int initCap=10){
capacity=(capacity>0)?capacity:1;
data=new float[capacity];
top=0;
}
~FloatStack(){
delete [] data;
}
FloatStack(const FloatStack&other){
capacity=other.capacity;
delete []data;
data=new float[capacity];
for(int i=0;i<other.top;i++){
data[i]=other.data[i];
}
}
FloatStack& operator=(const FloatStack&other){
if(this!=&other){
capacity=other.capacity;
delete []data;
data=new float[capacity];
for(int i=0;i<other.top;i++){
data[i]=other.data[i];
}
}
return *this;
}
void push(float val){
if(top>=capacity){
int newcapacity=capacity*1.5;
if(newcapacity<=capacity){
newcapacity=capacity+1;
}
float *newdata=new float[newcapacity];
for(int i=0;i<top;i++){
newdata[i]=data[i];
}
delete [] data;
data=newdata;
capacity=newcapacity;
}
data[top++]=val;
}
float pop(){
if(!top){
cout<<"栈中没有元素了"<<endl;
return 0.0;
}
return data[--top];
}
int getSize(){
return top;
}
void display(){
cout<<"Stack:[";
for(;top>0;){
cout<<data[--top]<<",";
}
cout<<data[0]<<"]"<<endl;
}
};
int main(){
FloatStack s1(3);
cout<<s1.getSize()<<endl;
s1.push(2.1);
cout<<s1.getSize()<<endl;
FloatStack s2;
s2=s1;
s2.push(3.1);
s2.push(4.1);
s2.display();
s2.pop();
s2.display();
return 0;
}
//5.28
#include <iostream>
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(const FloatStack &other)
{
top = other.top;
capacity = other.capacity;
data = new float[capacity];
for (int i = 0; i < top; ++i)
{
data[i] = other.data[i];
}
}
// 不需要delete []data,也不需要考虑自赋值,因为只有在构造的时候才会调用,其他的会调用那个赋值重载的
~FloatStack() { delete[] data; }
FloatStack &operator=(const FloatStack &other)
{
if (this != &other)
{ // 我们直接删除,不考虑是否栈满,直接用新对象的容量
delete[] data;
top = other.top;
capacity = other.capacity;
data = new float[capacity];
for (int i = 0; i < top; ++i)
{
data[i] = other.data[i];
}
}
}
void push(float val)
{
if (top >= capacity)
{
int newcapacity = capacity * 1.5;
if (newcapacity <= capacity)
{
newcapacity = capacity + 1;
}
float * newdata = new float [newcapacity];
for (int i = 0; i < top; ++i)
{
newdata[i] = data[i];
}
delete[] data;
data = newdata;
capacity = newcapacity;
}
data[top++] = val;
}
int getSize() const { return top; }
void display()
{
cout << "Stack:[";
for (int i = 0; i < top - 1; i++)
{
cout << data[i] << ",";
}
cout << data[top - 1] << "]" << endl;
}
float pop()
{
if (top <= 0)
{
cout << "栈空" << endl;
}
return data[--top];
}
};
五、
设计一个 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;
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class FixedDeposit
{
private:
// static int certificateID;//凭证编号 不能这样,不然定义多个对象,我们display就错了
static int nextID;
int certificateID;
string depositor;
string bankName;
double amount;
string status;
int depositMonth; //加个存入月份
public:
FixedDeposit(string name,string bank,double amt,int depositMonth): depositor(name),bankName(bank),depositMonth(depositMonth){
if(amt<0){
amount=0;
cout<<"Warning:Invalid amount set to 0"<<endl;
} else {
amount=amt;
}
certificateID=nextID++;
status="ACTIVE";
}
bool mature(int currentMonth,int depositMonths) {
if (currentMonth>= depositMonth+depositMonths)
//题目没给存入月份
{
status="MATURED";
return true;
}
status = "CANCELLED";
return false;
}
void display()const{
cout << "[ID:" << certificateID << "] "
<< fixed << setprecision(2) << amount
<< " from " << depositor
<< " at " << bankName
<< " -> " << status << endl;
}
string getStatus()const{
return status;}
double getAmount()const{
return amount;}
};
int FixedDeposit::nextID=2001;
int main(){
return 0;
}
六、
题目:设计一个 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 <iostream>
#include <string>
#include <iomanip> // 必须引入此头文件才能使用 setprecision
using namespace std;
class ProductPrice {
private:
string productName;
float price;
public:
// 1. 添加了 void 返回类型
void setInfo(string name, float p) {
if (p < 0) {
this->price = 0;
} else if (p > 1000) {
this->price = 1000;
} else {
this->price = p; // 2. 修复了 this0 的拼写错误
}
this->productName = name;
}
// 3. 返回类型改为 char,以匹配示例输出中的 Level: A/B/C/D/E
char getLevel() const {
// 使用连续的 <= 判断,可以完美覆盖浮点数情况
if (price <= 200) {
return 'A'; // 非常便宜
} else if (price <= 400) {
return 'B'; // 较便宜
} else if (price <= 600) {
return 'C'; // 中等
} else if (price <= 800) {
return 'D'; // 较贵
} else {
return 'E'; // 很贵
}
}
// 在不修改成员变量的函数后加上 const 是个好习惯(题中的“只读”概念)
bool isCheap() const {
return (price <= 400);
}
float getPrice() const {
return price;
}
void display() const {
// 4. 修复了全角冒号,并改用 setprecision(1)
cout << "Product: " << productName
<< ", Price: " << fixed << setprecision(1) << price
<< ", Level: " << getLevel()
<< ", Cheap: " << (isCheap() ? "YES" : "NO") << endl;
}
};
// 测试代码
int main() {
ProductPrice p1;
// 测试正常情况 (参考题目示例)
p1.setInfo("华为手机", 350.0);
p1.display();
// 测试越界情况 (<0 和 >1000)
ProductPrice p2;
p2.setInfo("便宜耳机", -50);
p2.display();
ProductPrice p3;
p3.setInfo("高级电脑", 1500);
p3.display();
return 0;
}
七、阅读程序写结果
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号