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;
}
运行结果:
四、总结
👉本文介绍了自定义类型的类型转换,先是介绍 转换构造函数 将其他类型转换为本类类型,然后介绍 类型转换运算符 将本类类型转换为其他类型。
热门推荐
2025世界航天:奋勇争先 力求突破
职场女性的服装搭配技巧
五大维度教你如何挑选最适合家的扫地机器人
什么是角膜屈光手术
【医疗问答】矫正散光手术该怎样选择?
劳动仲裁要求赔偿合法吗?详解赔偿流程与时间
销售合同违约怎么赔偿的
滥用益生菌可能让便秘加重?泻药到底怎么用
矿泉水瓶手工制作墙面装饰品:从废品到艺术品的创意转变
咖啡豆的三大原生种 咖啡的栽培条件
“自从我坚持每天做2遍这件事,头发越长越多了”
2025最全支付宝国际/跨境汇款攻略(流程+限额+手续费+到账时间+常见问题)
4届春晚龙洋坐稳董卿接班人之位,毕业3年太优秀,被安排央视工作
Excel中给文字添加序号的多种方法
伊瑞克提翁神庙:雅典保护神的居所
为什么要做胃肠镜检查?消化内镜的检查与治疗全解析
创业团队如何避免风险
朱顶红的养殖方法和注意事项
《平凡的世界》深度解析:路遥的创作生涯与人物塑造艺术
理解亩与平方米的换算关系:1亩等于666.67平方米的重要性解析
曹娥庙:江南第一庙的历史与文化
如何把人物画得更像,这3个方法请注意,来听听教授怎么说
工业自动化中的液位传感器:类型、应用与维护指南
洗衣机水位传感器工作原理及维护方法
红楼梦:绛珠草是什么草?细品文字才知不是人参,作者暗示了原型
新显示器画面反应慢的解决方法(优化显示器性能)
Windows 10/11玩游戏时第二显示器延迟怎么办?
探秘古代世子的身份与地位
沉浸式游戏推荐:十大耐玩沉浸式游戏排行
医院合同护士面试攻略:轻松应对面试官的问题