C++类型转换详解:转换构造函数与类型转换运算符
创作时间:
作者:
@小白创作中心
C++类型转换详解:转换构造函数与类型转换运算符
引用
CSDN
1.
https://blog.csdn.net/wkd_007/article/details/140060927
C++作为一种强大的编程语言,其类型转换机制是开发者必须掌握的重要内容。本文将详细介绍C++中自定义类型的类型转换,包括转换构造函数和类型转换运算符的定义、特点、声明、定义和使用方法。通过具体的代码示例和运行结果,帮助读者更好地理解这些概念。
一、概述
C++的内置类型之间会进行隐式的类型转换:
- char、short、int、long四个类型混合运算时,较小的(占用字节数小)整数类型会被自动提升为较大的(占用字节数大)整数类型,以确保不会丢失精度;
- signed类型 和 unsigned类型 混合运算的结果是 unsigned类型;
- 整型(char、short、int、long)和浮点类型(float、double)混合运算时,会自动提升为浮点类型;而且,较短的浮点数类型(如float)会被自动提升为更长的浮点数类型(如double)以进行混合运算,以确保不会丢失精度。
那么,自定义的类类型是否也可以进行类型转换呢?C++目标之一就是让自定义类型可以像内置类型一样使用,所以,C++提供了转换构造函数、类型转换运算符两种成员函数来支持类类型的类型转换。
二、转换构造函数(converting constructor)
这个小节解决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;
}
转换构造函数的使用
- 转换构造函数也是构造函数,所以可以直接用它创造对象。
CDate date(20240627); 赋值号
左边为类对象,右边为转换构造函数的形参类型时,会调用转换构造函数。
CDate date1 = 20240628;
下面是转换构造函数使用的完整例子:定义了三个转换构造函数,可以将
int
、
char*
、
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个问题:
- 为什么需要类型转换运算符?
- 什么是类型转换运算符?
- 怎样声明、定义类型转换运算符?
- 怎样使用类型转换运算符?
类型转换运算符:是类的成员函数,目的是将本类对象转换为指定类型对象。
类型转换运算符的特点:
- 函数原型没有返回值、没有参数;
- 函数名为关键字
operator 类型
,类型为要转换的类型; - 必须要有return语句,return的类型就是要转换为的类型;
- 必须是本类成员函数。
- 转换为的类型可以是内置类型,也可以是其他类类型;
- C++11支持使用关键字 explicit 限制隐式转换。
声明、定义类型转换运算符
下面以CDate类为例,定义一个将 CDate类型 转换成 int类型 的转换构造函数。
operator int(); // 类型转换运算符
// 类型转换运算符定义
CDate::operator int()
{
return (int)(m_year*10000 + m_mon*100 + m_day);
}
类型转换运算符的使用
- 类型转换运算符是成员函数,所以可以直调用它,但一般不这样做。
int i = date.operator int(); - 显示地将本类对象转换为其他类型对象,或将本类对象赋值给其他类型对象时,会调用类型转换运算符函数。
int i = date;
下面是类型转换运算符使用的完整例子,代码是使用上个小节代码修改的:定义了三个类型转换运算符,可以将
CDate
对象转换为
int
、
char*
、
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;
}
运行结果:
四、总结
👉本文介绍了自定义类型的类型转换,先是介绍 转换构造函数 将其他类型转换为本类类型,然后介绍 类型转换运算符 将本类类型转换为其他类型。
热门推荐
如何选择合适的入场时机并进行有效的投资操作?
建筑遗产保护与修复:方法、技术与案例研究
闪婚隐瞒病情是否违法?
马尔代夫岛屿排名:五个最受欢迎的度假天堂
深圳电子元器件进出口供应链,如何利用物联网技术提升供应链透明度?
现在为什么不创造新的汉字了?答案可能出乎你的意料!
监管沙箱的意义及其在金融创新中的体现
探索喜爱的音乐类型及其影响
蜀国并非一直最弱:三国时期的战略与实力分析
清明节的祭拜磕头与悼念仪式
唐伯虎《一世歌》:人生还有什么看不破的呢?醍醐灌顶,受益匪浅
SG3525脉宽调制控制器IC使用指南:引脚功能、参数设置与应用电路详解
企业破产终结后,债权人能否起诉股东承担责任?
全国首个系统关注卡车司机健康状况的调查报告发布
人活着,平淡是真,健康是福!
科学家终于解释 4,000 年前猛犸象灭绝的原因
洪洞大槐树 | 每期一姓——郭姓
血战淞沪,中国80万大军为何不敌25万日军?三个致命原因令人痛心
科普:运动,是对孩子大脑最好的投资!(附0-18岁分龄运动清单)
乌龟换壳全解析:从现象到内涵,一次说清
存量客户寻减负 商业银行争利润 提前还贷天平如何倾斜
东山岛7镇一日游攻略汇总(附路线图)
承德绝美景点揭秘!你绝对不能错过的八个地方!
7种他汀,7类不同人群,如何选择最适合自己的?一文讲出实情
AI影响下的存储市场:DRAM、NAND供需随动
如何依据兴趣爱好规划职业走向
烤煤炭头痛如何缓解
在线医疗咨询,改善就医体验的创新途径
诗歌的雅韵:探寻古诗的书写之美
在线课堂互动的八大益处:提高学习效率与参与感