《面向对象程序设计》专题1类型转换
开这个专题的原因
1.上机范围,4道程序阅读题全是类型转换的
2. 理论课期间,老师在第九章着重讲了这种类型的,前面几张也稍微的略有涉及的讲过
3. “类型转换考了2道题,20分”
上机范围 4道题复现
七、阅读程序写结果
#include <iostream>
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 <iostream>
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 <iostream>
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 <iostream>
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;
}
学习通上历次作业上的线索
练习(gemini && 豆包)
豆包的几道工程大题
大题 1:温度单位转换系统(基础必考题)
工程背景
在气象监测和工业控制中,经常需要在摄氏度 (Celsius)、华氏度 (Fahrenheit) 和开尔文 (Kelvin) 之间进行单位转换。请设计一个Temperature类,支持三种温度单位之间的隐式 / 显式转换。
具体要求
类设计:
私有成员:double celsius(内部统一存储摄氏度)
转换构造函数:
Temperature(double c = 0.0):从摄氏度构造
explicit Temperature(char unit, double value):从指定单位构造(unit='F' 表示华氏度,'K' 表示开尔文)
类型转换运算符:
operator double() const:转换为摄氏度(隐式)
explicit operator double() const:转换为华氏度(显式)
explicit operator double() const:转换为开尔文(显式)
成员函数:
void print() const:输出格式:25.00°C = 77.00°F = 298.15K
转换公式:
华氏度转摄氏度:(C=(F-32)\times\frac{5}{9})
开尔文转摄氏度:(C=K-273.15)
摄氏度转华氏度:(F=C\times\frac{9}{5}+32)
摄氏度转开尔文:(K=C+273.15)
测试要求:编写 main 函数,实现以下功能:
从摄氏度 25.0 构造温度对象
从华氏度 86.0 显式构造温度对象
从开尔文 300.0 显式构造温度对象
将温度对象隐式转换为 double(输出摄氏度)
将温度对象显式转换为华氏度和开尔文并输出
核心考点
转换构造函数与 explicit 关键字
多个类型转换运算符的重载
显式转换与隐式转换的区别
大题 2:货币兑换系统(进阶高频题)
工程背景
在跨境电商和金融系统中,需要支持不同货币之间的自动转换。请设计一个Currency类,支持人民币 (RMB)、美元 (USD) 和欧元 (EUR) 之间的转换。
具体要求
类设计:
私有成员:double rmb(内部统一存储人民币)
静态汇率常量:
static const double USD_TO_RMB; // 1美元=7.2人民币
static const double EUR_TO_RMB; // 1欧元=7.8人民币
转换构造函数:
Currency(double rmb = 0.0):从人民币构造
Currency(char type, double amount):从指定货币构造(type='U' 美元,'E' 欧元)
类型转换运算符:
operator double() const:转换为人民币
explicit operator double() const:转换为美元
explicit operator double() const:转换为欧元
重载加法运算符:
Currency operator+(const Currency& other) const:支持两个货币对象相加
成员函数:
void print() const:输出格式:100.00 RMB = 13.89 USD = 12.82 EUR
测试要求:编写 main 函数,实现以下功能:
创建人民币 100 元、美元 50 元、欧元 30 元三个对象
计算三个货币的总金额(人民币)
将总金额转换为美元和欧元并输出
验证:double total = rmbObj + usdObj + eurObj; 可以正常编译运行
核心考点
类型转换在算术运算中的隐式触发
运算符重载与类型转换的结合
静态成员变量的使用
大题 3:二维向量与标量转换系统(综合压轴题)
工程背景
在计算机图形学和物理模拟中,经常需要将二维向量 (Vector2D) 与标量 (Scalar) 进行转换(向量的模长)。请设计一个Vector2D类,支持向量与标量之间的转换,以及向量的基本运算。
具体要求
类设计:
私有成员:double x, y(x 和 y 分量)
构造函数:
Vector2D(double x = 0.0, double y = 0.0):从分量构造
explicit Vector2D(double magnitude):从模长构造(方向为 x 轴正方向)
类型转换运算符:
operator double() const:转换为向量的模长(隐式)
重载运算符:
Vector2D operator+(const Vector2D& other) const:向量加法
Vector2D operator(double scalar) const:向量与标量乘法
friend Vector2D operator(double scalar, const Vector2D& v):标量与向量乘法
成员函数:
double dot(const Vector2D& other) const:点积
void print() const:输出格式:(3.00, 4.00), magnitude: 5.00
测试要求:编写 main 函数,实现以下功能:
创建向量 v1 (3,4) 和 v2 (5,12)
计算 v1 的模长(直接用double len = v1;)
计算 v1 + v2 的模长
计算 2 * v1 的模长
从模长 10 构造一个向量并输出
核心考点
类型转换在表达式中的隐式转换
友元函数与运算符重载
转换构造函数的 explicit 使用
大题 4:时间单位转换系统(易错题)
工程背景
在计时系统中,经常需要在秒、分钟、小时之间进行转换。请设计一个Time类,支持不同时间单位之间的转换,并防止错误的隐式转换。
具体要求
类设计:
私有成员:int seconds(内部统一存储秒数)
转换构造函数:
explicit Time(int s = 0):从秒构造(禁止隐式转换)
Time(char unit, int value):从指定单位构造(unit='m' 分钟,'h' 小时)
类型转换运算符:
explicit operator int() const:转换为秒
explicit operator double() const:转换为分钟
explicit operator double() const:转换为小时
重载加法运算符:
Time operator+(const Time& other) const
成员函数:
void print() const:输出格式:3661 seconds = 61.02 minutes = 1.02 hours
测试要求:编写 main 函数,验证以下代码:cpp运行// Time t1 = 60; // 这行应该编译错误(因为构造函数是explicit)
Time t2(120); // 正确
Time t3('m', 5); // 5分钟=300秒
Time t4('h', 1); // 1小时=3600秒
Time total = t2 + t3 + t4;
total.print();
int s = (int)total;
double m = (double)total;
double h = (double)total;
cout << s << " " << m << " " << h << endl;
核心考点
explicit 关键字的正确使用
禁止隐式转换的场景
多个显式转换函数的调用
大题 5:分数与浮点数转换系统(经典题)
工程背景
在科学计算中,有时需要用分数 (Fraction) 来精确表示有理数,同时需要支持分数与浮点数之间的转换。请设计一个Fraction类,支持分数的基本运算和与浮点数的转换。
具体要求
类设计:
私有成员:int numerator, denominator(分子和分母,始终保持最简形式)
构造函数:
Fraction(int num = 0, int den = 1):从分子分母构造
explicit Fraction(double value):从浮点数构造(精确到小数点后 6 位)
类型转换运算符:
operator double() const:转换为浮点数(隐式)
重载运算符:
Fraction operator+(const Fraction& other) const
Fraction operator*(const Fraction& other) const
私有辅助函数:
void simplify():约分,将分数化为最简形式
成员函数:
void print() const:输出格式:3/4 = 0.75
测试要求:编写 main 函数,实现以下功能:
创建分数 f1 (1,2) 和 f2 (1,3)
计算 f1 + f2 并输出
计算 f1 * f2 并输出
将 f1 转换为浮点数并输出
从浮点数 0.6 构造一个分数并输出
核心考点
浮点数到类类型的转换构造函数
类类型到浮点数的类型转换运算符
分数的约分算法
考试答题技巧(类型转换大题满分必备)
内部统一存储原则:所有转换都基于一个内部统一的单位(如温度统一存摄氏度,时间统一存秒),这样转换逻辑最清晰,不容易出错。
explicit 关键字使用原则:
单参数构造函数默认加上 explicit,除非你明确需要隐式转换
类型转换运算符默认加上 explicit,除非是转换为 bool 或者最常用的单位
转换顺序:
其他类型 → 类对象:用转换构造函数
类对象 → 其他类型:用类型转换运算符
避免二义性:不要同时提供多个可以匹配同一转换的函数,否则会编译错误。
豆包的几道阅读程序写结果
所有题目都围绕两个核心机制展开,你只要把这两个搞懂,20 分稳拿:
- 转换构造函数
定义:只有一个参数的构造函数
作用:允许将其他类型的值隐式转换为类对象
例子:Score s = 95; 等价于 Score s(95); - 类型转换运算符
定义:operator 目标类型() const { ... }
作用:允许将类对象隐式转换为其他类型的值
例子:cout << s << endl; 等价于 cout << (int)s << endl; - 必考陷阱
输出顺序:先执行构造函数输出,再执行类型转换输出
隐式转换触发时机:赋值、算术运算、函数参数传递、cout 输出
多个转换函数的优先级:精确匹配 > 标准转换 > 用户定义转换
三、4 道全真模拟题(难度与考试完全一致)
模拟题 1(基础题,必考难度)
cpp
运行
#include <iostream>
using namespace std;
class Temperature {
private:
double celsius;
public:
Temperature(double c = 0.0) : celsius(c) {
cout << "constructing " << c << "C" << endl;
}
operator double() const {
cout << "convert to Fahrenheit" << endl;
return celsius * 9.0 / 5.0 + 32.0;
}
};
int main() {
Temperature t = 25.0;
double f = t;
cout << f << endl;
return 0;
}
答案与解析:
plaintext
constructing 25C
convert to Fahrenheit
77
Temperature t = 25.0; 调用转换构造函数,输出第一行
double f = t; 触发类型转换运算符,输出第二行
cout << f << endl; 输出转换后的华氏温度 77
模拟题 2(进阶题,高频考点)
#include <iostream>
using namespace std;
class Distance {
private:
int meters;
public:
Distance(int m = 0) : meters(m) {
cout << "constructing " << m << "m" << endl;
}
operator int() const {
cout << "convert to meters" << endl;
return meters;
}
operator double() const {
cout << "convert to kilometers" << endl;
return meters / 1000.0;
}
};
int main() {
Distance d(1500);
cout << d << endl;
cout << (double)d << endl;
return 0;
}
答案与解析:
plaintext
constructing 1500m
convert to meters
1500
convert to kilometers
1.5
Distance d(1500); 调用构造函数,输出第一行
cout << d << endl; 优先匹配operator int()(因为 cout 对 int 的重载更精确),输出第二、三行
cout << (double)d << endl; 显式指定转换为 double,调用operator double(),输出第四、五行
模拟题 4 这个可能真有坑,老师课上讲过
#include <iostream>
using namespace std;
class Number {
private:
int value;
public:
Number(int v = 0) : value(v) {
cout << "constructing " << v << endl;
}
Number operator+(const Number& other) const {
cout << "operator+ called" << endl;
return Number(value + other.value);
}
operator int() const {
cout << "convert to int" << endl;
return value;
}
};
int main() {
Number n1(10);
Number n2 = n1 + 20;
cout << n2 << endl;
return 0;
}
constructing 10
convert to int
constructing 30
convert to int
30
答案与解析:
constructing 10
convert to int
constructing 30
convert to int
30
这道题有二义性 编译不通过
算术运算中:类对象会被转换为基本类型,然后执行基本类型的运算
浙公网安备 33010602011771号