【C++ | 类型转换】转换构造函数、类型转换运算符 详解及例子源码

😁博客主页😁:🚀https://blog.csdn.net/wkd_007🚀
🤑博客内容🤑:🍭嵌入式开发、Linux、C语言、C++、数据结构、音视频🍭
⏰发布时间⏰:

本文未经允许,不得转发!!!

目录

  • 🎄一、概述
  • 🎄二、转换构造函数(converting constructor)
  • 🎄三、类型转换运算符(conversion operator)
  • 🎄四、总结



在这里插入图片描述

🎄一、概述

C++的内置类型之间会进行隐式的类型:

  • 1、char、short、int、long四个类型混合运算时,较小的(占用字节数小)整数类型会被自动提升为较大的(占用字节数大)整数类型,以确保不会丢失精度;
  • 2、signed类型 和 unsigned类型 混合运算的结果是 unsigned类型;
  • 3、整型(char、short、int、long)和浮点类型(float、double)混合运算时,会自动提升为浮点类型;而且,较短的浮点数类型(如float)会被自动提升为更长的浮点数类型(如double)以进行混合运算,以确保不会丢失精度。

在这里插入图片描述
那么,自定义的类类型是否也可以进行类型转换呢?

C++目标之一就是让自定义类型可以像内置类型一样使用,所以,C++提供了 转换构造函数类型转换运算符 两种成员函数来支持类类型的类型转换。


在这里插入图片描述

🎄二、转换构造函数(converting constructor)

这个小节解决4个问题:
1、为什么需要 转换构造函数
2、什么是 转换构造函数
3、怎样声明、定义 转换构造函数
4、怎样使用 转换构造函数

转换构造函数:属于构造函数的一种,目的是让其他类型的对象可以转换成本类对象。

转换构造函数的几个特点:
1、属于构造函数的一种,没有返回值,函数名和类名一样;
2、只有一个形参,或其他形参都有默认值;
3、形参类型可以是内置类型,也可以是其他类类型;
4、可以使用关键字 explicit 限制隐式转换。

声明、定义转换构造函数
下面以CDate类为例,定义一个将int类型转换成CDate类型的转换构造函数。只接收一个int类型参数:

CDate(int intDate); // 类内声明// 转换构造函数定义
CDate::CDate(int intDate)
{m_year = intDate / 10000;m_mon = (intDate / 100) % 100;m_day = intDate % 100;cout << "Calling Converting Constructor(int)" << ", this=" << this <<endl;
}

转换构造函数的使用
1、转换构造函数也是构造函数,所以可以直接用它创造对象。CDate date(20240627);
2、赋值号=左边为类对象,右边为转换构造函数的形参类型时,会调用转换构造函数。CDate date1 = 20240628;
下面是转换构造函数使用的完整例子:定义了三个转换构造函数,可以将intchar*CDateStr对象转换为CDate对象,其中CDateStr为类类型。

// g++ 20_Trans_Date.cpp
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;class CDateStr
{
public:CDateStr(int year, int mon, int day){sprintf(str, "%d.%d.%d", year, mon, day);cout << "DateStr: " << str << endl;}const char *GetStr() const{return str;}
private:enum {MAX_STR_NUM=64};char str[MAX_STR_NUM];
};class CDate
{
public:CDate(int year, int mon, int day);	// 构造函数声明CDate(int intDate);					// 转换构造函数声明CDate(const char *str);				// 转换构造函数声明explicit CDate(const CDateStr &str, int i=0);// 带默认值参数的转换构造函数void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << ", this=" << this << endl;}
private:int m_year;int m_mon;int m_day;
};// 构造函数定义
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;cout << "Calling Constructor" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(int intDate)
{m_year = intDate / 10000;m_mon = (intDate / 100) % 100;m_day = intDate % 100;cout << "Calling Converting Constructor(int)" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(const char *str)
{if(0 == sscanf(str, "%d.%d.%d", &m_year, &m_mon, &m_day)){m_year=m_mon=m_day=0;}cout << "Calling Converting Constructor(char*)" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(const CDateStr &str, int i)
{if(0 == sscanf(str.GetStr(), "%d.%d.%d", &m_year, &m_mon, &m_day)){m_year=m_mon=m_day=0;}cout << "Calling Converting Constructor(CDateStr)" << ", this=" << this <<endl;
}int main()
{CDate date(20240627);date.show();cout << endl;CDate date1 = 20240628;date1.show();cout << endl;date1 = "2024.06.29";date1.show();cout << endl;CDateStr dateStr(2024,06,30);date1 = (CDate)dateStr;date1.show();cout << endl;return 0;
}

运行结果:
在这里插入图片描述


在这里插入图片描述

🎄三、类型转换运算符(conversion operator)

转换构造函数(converting constructor)可以将其他类型的对象转换为本类类型对象。那么怎样将类对象转换为其他类型对象呢?可以使用类型转换运算符(conversion operator)。

这个小节解决4个问题:
1、为什么需要类型转换运算符
2、什么是类型转换运算符
3、怎样声明、定义类型转换运算符
4、怎样使用类型转换运算符

类型转换运算符:是类的成员函数,目的是将本类对象转换为指定类型对象。

类型转换运算符的特点:
1、函数原型没有返回值、没有参数;
2、函数名为关键字operator 类型,类型为要转换的类型;
3、必须要有return语句,return的类型就是要转换为的类型;
4、必须是本类成员函数。
5、转换为的类型可以是内置类型,也可以是其他类类型;
6、C++11支持使用关键字 explicit 限制隐式转换。

声明、定义类型转换运算符
下面以CDate类为例,定义一个将 CDate类型 转换成 int类型 的转换构造函数。

operator int();		// 类型转换运算符// 类型转换运算符定义
CDate::operator int()
{return (int)(m_year*10000 + m_mon*100 + m_day);
}

类型转换运算符的使用
1、类型转换运算符是成员函数,所以可以直调用它,但一般不这样做。int i = date.operator int();
2、显示地将本类对象转换为其他类型对象,或将本类对象赋值给其他类型对象时,会调用类型转换运算符函数。int i = date;
下面是类型转换运算符使用的完整例子,代码是使用上个小节代码修改的:定义了三个类型转换运算符,可以将CDate对象转换为intchar*CDateStr对象,其中CDateStr为类类型。

// g++ 20_Trans_Date.cpp -std=gnu++11
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;class CDateStr
{
public:CDateStr(int year, int mon, int day){sprintf(str, "%d.%d.%d", year, mon, day);cout << "DateStr: " << str << endl;}const char *GetStr() const{return str;}
private:enum {MAX_STR_NUM=64};char str[MAX_STR_NUM];
};class CDate
{
public:CDate(int year, int mon, int day);	// 构造函数声明CDate(int intDate);					// 转换构造函数声明CDate(const char *str);				// 转换构造函数声明explicit CDate(const CDateStr &str, int i=0);// 带默认值参数的转换构造函数operator int();		// 类型转换运算符operator char*();	// 类型转换运算符explicit operator CDateStr();// 类型转换运算符, C++11支持explicit禁用隐式转换void show(){cout << "Date: " << m_year << "." << m_mon << "." << m_day << ", this=" << this << endl;}
private:int m_year;int m_mon;int m_day;
};// 构造函数定义
CDate::CDate(int year, int mon, int day)
{m_year = year;m_mon = mon;m_day = day;cout << "Calling Constructor" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(int intDate)
{m_year = intDate / 10000;m_mon = (intDate / 100) % 100;m_day = intDate % 100;cout << "Calling Converting Constructor(int)" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(const char *str)
{if(0 == sscanf(str, "%d.%d.%d", &m_year, &m_mon, &m_day)){m_year=m_mon=m_day=0;}cout << "Calling Converting Constructor(char*)" << ", this=" << this <<endl;
}// 转换构造函数定义
CDate::CDate(const CDateStr &str, int i)
{if(0 == sscanf(str.GetStr(), "%d.%d.%d", &m_year, &m_mon, &m_day)){m_year=m_mon=m_day=0;}cout << "Calling Converting Constructor(CDateStr)" << ", this=" << this <<endl;
}// 类型转换运算符定义
CDate::operator int()
{return (int)(m_year*10000 + m_mon*100 + m_day);
}// 类型转换运算符定义,用完要是否内存
CDate::operator char*()
{char *str = new char[64];sprintf(str, "%4d.%02d.%02d", m_year, m_mon, m_day);return str;
}// 类型转换运算符定义
CDate::operator CDateStr()
{CDateStr dateStr(m_year, m_mon, m_day);return dateStr;
}int main()
{CDate date(20240627);date.show();cout << endl;CDate date1 = 20240628;date1.show();cout << endl;date1 = "2024.06.29";date1.show();cout << endl;CDateStr dateStr(2024,06,30);date1 = (CDate)dateStr;date1.show();cout << endl;int i = date;//int i = date.operator int();cout << i << endl;cout << endl;char *str = date;cout << str << endl;cout << endl;delete[] str;CDateStr datestr = (CDateStr)date;cout << datestr.GetStr() << endl;cout << endl;return 0;
}

运行结果:
在这里插入图片描述


在这里插入图片描述

🎄四、总结

👉本文介绍了自定义类型的类型转换,先是介绍 转换构造函数 将其他类型转换为本类类型,然后介绍 类型转换运算符 将本类类型转换为其他类型。

在这里插入图片描述
如果文章有帮助的话,点赞👍、收藏⭐,支持一波,谢谢 😁😁😁

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/36562.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

git 代码回退 soft hard区别

一:只是本地修改提交到本地版本库仓库,代码如何回退 git hard 回退 会清除掉 你当前修改的所有文件代码内容 或添加的新文件 把当前文件恢复到没有修改前的状态 git soft 回退 不会清除掉 你当前修改的所有文件代码内容 或添加的新文件 把当前文件恢复到当时修改时的状…

Linux /proc目录总结

1、概念 在Linux系统中&#xff0c;/proc目录是一个特殊的文件系统&#xff0c;通常被称为"proc文件系统"或"procfs"。这个文件系统以文件系统的方式为内核与进程之间的通信提供了一个接口。/proc目录中的文件大多数都提供了关于系统状态的信息&#xff0…

Linux容器篇-Docker容器的使用

文章目录 前言一、Docker的安装主机环境准备关闭防火墙关闭selinux时间同步关闭 swap配置操作系统yum源配置国内Docker-ce镜像源注意 二、安装docker-ce三、配置镜像加速器阿里云镜像加速器生成 四、Docker的使用Docker 客户端获取镜像启动容器查看所有的容器&#xff1a;启动已…

【Python】已解决:ModuleNotFoundError: No module named ‘LAC‘

文章目录 一、分析问题背景二、可能出错的原因三、错误代码示例四、正确代码示例五、注意事项 已解决&#xff1a;ModuleNotFoundError: No module named ‘LAC‘ 一、分析问题背景 在开发或运行Python程序时&#xff0c;可能会遇到各种各样的报错&#xff0c;其中“ModuleNo…

安装OpenHarmony编译库和工具集

一、搭建开发环境 1.1、Ubuntu搭建&#xff0c;参考 VMware完美安装Ubuntu20.04-CSDN博客文章浏览阅读286次&#xff0c;点赞5次&#xff0c;收藏3次。详细介绍了VMware下安装Ubuntu20.04https://blog.csdn.net/longyuzi/article/details/139935769 1.2、拉取OpenHarmony源码…

Android studio Logcat 功能介绍

介绍 Android Studio Jellyfish版本下logcat功能&#xff0c;不同的tag会有不同的颜色&#xff0c;不同level等级的log默认也有不同的颜色。log过滤修改的更简洁了&#xff0c;原先的log视图只需要勾选就可以选择不同level的log了&#xff0c;当前需要在输入框中进行过滤器匹配…

正版软件 | R-Studio Corporate:企业级数据恢复的终极解决方案

数据是企业的生命线&#xff0c;而数据丢失可能随时威胁到企业的正常运营。R-Studio Corporate 是一款专为企业环境设计的多功能数据恢复软件&#xff0c;确保您在面临数据危机时&#xff0c;能够迅速、高效地恢复宝贵数据。 跨平台操作&#xff0c;灵活恢复 R-Studio Corporat…

从灵感到实践:Kimi辅助完成学术论文选题的文艺之旅

学境思源&#xff0c;一键生成论文初稿&#xff1a; AcademicIdeas - 学境思源AI论文写作 昨天我们为大家介绍了ChatGPT辅助完成实现设计&#xff08;AI与学术的交响&#xff1a;ChatGPT辅助下的实验设计新篇章&#xff09;。今天我们再来看看Kimi对于论文选题都能提供哪些帮助…

【一生一芯】笔记

文章目录 一级目录二级目录三级目录缓存的验证 一级目录 二级目录 三级目录 缓存的验证

阿里云 CosyVoice 语音合成大模型 API 实践

前言 最近大模型这么火&#xff0c;就想着玩一下&#xff0c;作为非 AI 从业者&#xff0c;最好的方式就是调用云服务的 API 来构建自己的 AI 应用。首选当然是国外的 ChatGPT API&#xff0c;但是说实话那个玩意有点贵&#xff0c;而且最近国内也被封禁不让调用了&#xff0c…

计算机毕业设计hadoop+spark+hive知识图谱酒店推荐系统 酒店数据分析可视化大屏 酒店爬虫 高德地图API 酒店预测系统 大数据毕业设计

酒店推荐系统开题报告 一、研究背景与意义 随着旅游业的蓬勃发展和人们生活水平的提高&#xff0c;酒店行业迎来了前所未有的发展机遇。然而&#xff0c;面对众多的酒店选择&#xff0c;消费者往往难以在短时间内找到最适合自己需求和预算的酒店。因此&#xff0c;开发一款高…

晋级国赛!卓翼飞思技术引领,助力辽宁赛区机器人及人工智能大赛圆满收官

近日&#xff0c;第二十六届中国机器人及人工智能大赛—辽宁赛区选拔赛在大连海事大学圆满收官。本次大赛吸引来自辽宁工业大学、大连理工大学等知名高校的10余支队伍参与&#xff0c;充分展现各高校在机器人及人工智能领域的深厚实力和创新精神。其中&#xff0c;由卓翼飞思实…

【排序算法】—— 希尔排序

目录 一、希尔排序原理 二、希尔排序的思路 三、希尔排序为什么快 四、如何取增量 五、源码 希尔排序是简单插入排序的一种升级版&#xff0c;它也是用了插入的思想&#xff0c;而插入排序相比冒泡排序和选择排序的效率要高的多&#xff0c;再将它优化为希尔排序后效率跟原…

51单片机STC89C52RC——12.1 数据存储芯片AT24C02

目的/效果 利用存储芯片AT24C02存储数据&#xff0c;LCD1602显示存储的数据。 一&#xff0c;STC单片机模块 二&#xff0c;AT24C02存储芯片 2.1 介绍 AT24C02是一个2K位串行CMOS E2PROM&#xff0c;内部含有256个8位字节&#xff0c;采用先进CMOS技术实质上减少了器件的功…

通讯录管理系统——查找联系人

功能描述&#xff1a;按照姓名查看指定联系人的信息 查看联系人实现步骤 1.封装查找联系人函数 2.测试查找指定联系人 一、封装查找联系人函数 实现思路&#xff1a;判断用户指定的联系人是否存在&#xff0c;如果存在&#xff0c;显示信息&#xff0c;不存在提示查无此人…

如何在FastAPI服务器中添加黑名单和白名单实现IP访问控制

文章目录 📖 介绍 📖🏡 演示环境 🏡📒 文章内容 📒📝 添加黑名单功能步骤1:安装依赖步骤2:创建FastAPI应用步骤3:添加黑名单📝 添加白名单功能步骤1:创建白名单列表步骤2:添加白名单检查⚓️ 相关链接 ⚓️📖 介绍 📖 在现代网络应用开发中,为了增强…

C++【引用】

P. S.&#xff1a;以下代码均在VS2019环境下测试&#xff0c;不代表所有编译器均可通过。 P. S.&#xff1a;测试代码均未展示头文件stdio.h的声明&#xff0c;使用时请自行添加。 博主主页&#xff1a;LiUEEEEE                        …

进程间通信简介-I.MX6U嵌入式Linux C应用编程学习笔记基于正点原子阿尔法开发板

进程间通信简介 进程间通信简介 进程间进程简称IPC(interprocess communication)&#xff0c;进程间通信就是在不同进程之间传递信息或交换信息 进程间通信的目的 数据传输&#xff1a;一个进程需要将它的数据发送给另一个进程 资源共享&#xff1a;多个进程之间共享同样的…

武汉星起航:一站式服务,助力亚马逊卖家高效运营,实现收益飞跃

在跨境电商的浪潮中&#xff0c;武汉星起航电子商务有限公司以其独特的一站式跨境电商服务&#xff0c;为众多亚马逊卖家提供了强有力的支持&#xff0c;助力他们在不断发展的市场中脱颖而出&#xff0c;实现收益的大幅提升。 武汉星起航的一站式跨境电商服务&#xff0c;以其…

JAVA医院绩效考核系统源码:三级公立医院绩效考核系统源码 可源码交付,支持二开

JAVA医院绩效考核系统源码&#xff1a;三级公立医院绩效考核系统源码 可源码交付&#xff0c;支持二开 医院绩效考核系统是一个集数据采集、分析、评估、反馈于一体的信息化工具&#xff0c;旨在提高医疗服务质量、优化资源配置、促进医院可持续发展。以下是对医院绩效考核系统…