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;
}
运行结果:
四、总结
👉本文介绍了自定义类型的类型转换,先是介绍 转换构造函数 将其他类型转换为本类类型,然后介绍 类型转换运算符 将本类类型转换为其他类型。
热门推荐
奥运会的秘密武器:甜菜根可以提升运动表现
当内卷遭遇AI,IT招聘爆发人工智能大战
如何处理脚部出汗严重引起的脚丫烂、脚臭和水泡
足底“水泡”,千万别乱挠!
英伟达遭遇美国史上最严AI芯片出口管控
线性回归——基于燃油汽车效率数据集
空气循环净化器在不同季节的使用技巧与维护指南
细赏紫禁城 之 坤宁宫
揭秘故宫:满族最重要的宫殿建筑群——内廷后三宫
籍姓氏的由来与演变,历史是什么样的?
车祸报警多少天有效?交通事故处理全攻略
基于LabVIEW的汽车状态监测系统设计与实现
KTV有偿陪酒违法吗?财物损坏如何处理?
茶叶蛋和水煮蛋哪个更有营养,茶叶蛋和水煮蛋哪个热量高
崇明水仙怎么养,只需做好这三步!
公司设立股东会决议是怎样的
买车必看:汽车保险计算方式全解析
深蓝 G318 车的颜色会影响车内温度吗?
解决空调不制冷的原因及方法
申请住房公积金个人住房贷款需提供的材料是什么
股票“ST”会提前公告吗?一文详解相关问题
法学省考岗位2024年法学类公务员职位挑战
从耳垂看一个人的性格与命运
年假“应休未休”该如何处理
火化中"复活"的伦理与法律难题
为了211去偏远地区值吗?一本和偏远211如何选?附偏远211大学名单!
装修剩的木板别扔,能做出12件实用家居小物
35CrMo钢的热处理工艺及其应用
35CrMo材料详细描述
张量并行:大模型训练中的分布式技术详解