有关C++中类类型转换操作符总结(必看篇)
发布时间 - 2026-01-10 22:25:27 点击率:次实例如下:
class SmallInt {
public:
SmallInt(int i = 0): val(i)
{
if (i < 0 || i > 255)
throw std::out_of_range("Bad SmallInt initializer");
}
operator int() const { return val; }
private:
std::size_t val;
};
转换函数采用如下通用形式:
operator type();
type表示内置类型名、类类型名或由类型别名定义的名字。对任何可作为函数返回类型的类型(除了 void 之外)都可以定义转换函数。一般而言,不允许转换为数组或函数类型,转换为指针类型(数据和函数指针)以及引用类型是可以的。转换函数必须是成员函数,不能指定返回类型,并且形参表必须为空。operator int 返回一个 int 值;如果定义 operator Sales_item,它将返回一个 Sales_item 对象,诸如此类。转换函数一般不应该改变被转换的对象。因此,转换操作符通常应定义为 const 成员。
SmallInt si;
double dval;
si >= dval // si converted to int and then convert todouble
优点:类类型转换可能是实现和使用类的一个好处。通过为 SmallInt 定义到int 的转换,能够更容易实现和使用 SmallInt 类。int 转换使 SmallInt 的用户能够对 SmallInt 对象使用所有算术和关系操作符,而且,用户可以安全编写将 SmallInt 和其他算术类型混合使用的表达式。定义一个转换操作符就能代替定义 48个(或更多)重载操作符,类实现者的工作就简单多了。
缺点:二义性
class SmallInt {
public:
SmallInt(int= 0);
SmallInt(double);
//Usually it is unwise to define conversions to multiple arithmetic types
operatorint() const { return val; }
operatordouble() const { return val; }
private:
std::size_tval;
};
void compute(int);
void fp_compute(double);
void extended_compute(long double);
SmallInt si;
compute(si); // SmallInt::operator int() const
fp_compute(si); // SmallInt::operator double() const
extended_compute(si); // error: ambiguous
对 extended_compute 的调用有二义性。可以使用任一转换函数,但每个都必须跟上一个标准转换来获得 long double,因此,没有一个转换比其他的更好,调用具有二义性。
如果两个转换操作符都可用在一个调用中,而且在转换函数之后存在标准转换,则根据该标准转换的类别选择最佳匹配。若无最佳匹配,就会出现二义性。
再比如:
可能存在两个转换操作符,也可能存在两个构造函数可以用来将一个值转换为目标类型。
考虑 manip 函数,它接受一个 SmallInt 类型的实参:
void manip(const SmallInt &); double d; int i; long l; manip(d); // ok: use SmallInt(double) to convert theargument manip(i); // ok: use SmallInt(int) to convert theargument manip(l); // error: ambiguous
第三个调用具有二义性。没有构造函数完全匹配于 long。使用每一个构造函
数之前都需要对实参进行转换:
1. 标准转换(从 long 到double)后跟 SmallInt(double)。
2. 标准转换(从 long 到int)后跟 SmallInt(int)。
这些转换序列是不能区别的,所以该调用具有二义性。
当两个类定义了相互转换时,很可能存在二义性:
class Integral;
class SmallInt {
public:
SmallInt(Integral);// convert from Integral to SmallInt
};
class Integral {
public:
operatorSmallInt() const; // convert from Integral to SmallInt
};
void compute(SmallInt);
Integral int_val;
compute(int_val); // error: ambiguous
实参 int_val 可以用两种不同方式转换为 SmallInt 对象,编译器可以使
用接受 Integral 对象的构造函数,也可以使用将 Integral 对象转换为
SmallInt 对象的 Integral 转换操作。因为这两个函数没有高下之分,所以这
个调用会出错。
在这种情况下,不能用显式类型转换来解决二义性——显式类型转换本身既可以使用转换操作又可以使用构造函数,相反,需要显式调用转换操作符或构造函数:
compute(int_val.operator SmallInt()); // ok: useconversion operator compute(SmallInt(int_val)); // ok: use SmallInt constructor
改变构造函数以接受 const Integral 引用:
class SmallInt {
public:
SmallInt(constIntegral&);
};
则对compute(int_val) 的调用不再有二义性!原因在于使用 SmallInt构造函数需要将一个引用绑定到 int_val,而使用 Integral 类的转换操作符可以避免这个额外的步骤。这一小小区别足以使我们倾向于使用转换操作符。
显式强制转换消除二义性
class SmallInt {
public:
// Usually it is unwise to define conversions tomultiple
arithmetic types
operatorint() const { return val; }
operatordouble() const { return val; }
// ...
private:
std::size_tval;
};
void compute(int);
void compute(double);
void compute(long double);
SmallInt si;
compute(si); // error: ambiguous
可以利用显式强制转换来消除二义性:
compute(static_cast<int>(si)); // ok: convertand call compute(int)
显式构造函数调用消除二义性
class SmallInt {
public:
SmallInt(int= 0);
};
class Integral {
public:
Integral(int= 0);
};
void manip(const Integral&);
void manip(const SmallInt&);
manip(10); // error: ambiguous
可以用显示构造函数消除二义性:
manip(SmallInt(10)); // ok: call manip(SmallInt) manip(Integral(10)); // ok: call manip(Integral)
标准转换优于类类型转换
class LongDouble
{
public:
LongDouble(double );
//…
};
void calc( int );
void calc( LongDouble );
double dval;
calc( dval ); // which function
最佳可行函数是voidcalc(int), 调用此函数的转换为:将实参double类型转换为int类型的,为标准转换;调用voidcalc( LongDouble)函数时,将实参从double转换为LongDouble类型,为类类型转换,因为标准转换优于类类型转换,所以第一个函数为最佳可行函数。
以上这篇有关C++中类类型转换操作符总结(必看篇)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
# c
# 类型转换操作符
# C++超详细讲解逗号操作符
# C++中操作符的前置与后置有什么区别
# 详解C++赋值操作符重载
# C++-操作符重载、并实现复数类详解
# 浅谈C++虚重载操作符 virtual operator= 的使用方法
# C++超详细讲解逻辑操作符
# 转换为
# 可以用
# 给大家
# 可以使用
# 这一
# 就会
# 第一个
# 就能
# 两种
# 这两个
# 希望能
# 很可能
# 使我
# 诸如此类
# 这篇
# 不能用
# 用户可以
# 第三个
# 更容易
# 既可
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
Windows Hello人脸识别突然无法使用
详解Android——蓝牙技术 带你实现终端间数据传输
简单实现Android文件上传
如何获取PHP WAP自助建站系统源码?
SQL查询语句优化的实用方法总结
LinuxCD持续部署教程_自动发布与回滚机制
如何在服务器上三步完成建站并提升流量?
uc浏览器二维码扫描入口_uc浏览器扫码功能使用地址
javascript和jQuery中的AJAX技术详解【包含AJAX各种跨域技术】
Laravel如何将应用部署到生产服务器_Laravel生产环境部署流程
如何用西部建站助手快速创建专业网站?
如何用狗爹虚拟主机快速搭建网站?
Win11怎么修改DNS服务器 Win11设置DNS加速网络【指南】
香港网站服务器数量如何影响SEO优化效果?
如何快速辨别茅台真假?关键步骤解析
Laravel如何监控和管理失败的队列任务_Laravel失败任务处理与监控
如何在云虚拟主机上快速搭建个人网站?
中国移动官方网站首页入口 中国移动官网网页登录
如何在HTML表单中获取用户输入并用JavaScript动态控制复利计算循环
网站建设要注意的标准 促进网站用户好感度!
焦点电影公司作品,电影焦点结局是什么?
javascript中数组(Array)对象和字符串(String)对象的常用方法总结
Laravel项目结构怎么组织_大型Laravel应用的最佳目录结构实践
Laravel如何处理文件下载请求?(Response示例)
Laravel如何构建RESTful API_Laravel标准化API接口开发指南
如何基于云服务器快速搭建网站及云盘系统?
详解Android图表 MPAndroidChart折线图
高防服务器租用如何选择配置与防御等级?
Laravel如何处理和验证JSON类型的数据库字段
浅谈redis在项目中的应用
零基础网站服务器架设实战:轻量应用与域名解析配置指南
如何快速重置建站主机并恢复默认配置?
Laravel Session怎么存储_Laravel Session驱动配置详解
详解Nginx + Tomcat 反向代理 负载均衡 集群 部署指南
Laravel Sail是什么_基于Docker的Laravel本地开发环境Sail入门
rsync同步时出现rsync: failed to set times on “xxxx”: Operation not permitted
如何在香港免费服务器上快速搭建网站?
Laravel如何使用Livewire构建动态组件?(入门代码)
Java解压缩zip - 解压缩多个文件或文件夹实例
php嵌入式断网后怎么恢复_php检测网络重连并恢复硬件控制【操作】
广州网站制作公司哪家好一点,广州欧莱雅百库网络科技有限公司官网?
Midjourney怎么调整光影效果_Midjourney光影调整方法【指南】
如何在阿里云虚拟主机上快速搭建个人网站?
利用python获取某年中每个月的第一天和最后一天
详解jQuery停止动画——stop()方法的使用
Android中Textview和图片同行显示(文字超出用省略号,图片自动靠右边)
Laravel怎么防止CSRF攻击_Laravel CSRF保护中间件原理与实践
购物网站制作费用多少,开办网上购物网站,需要办理哪些手续?
厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?
Laravel如何实现用户密码重置功能?(完整流程代码)

