问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

C++类型转换详解:转换构造函数与类型转换运算符

创作时间:
作者:
@小白创作中心

C++类型转换详解:转换构造函数与类型转换运算符

引用
CSDN
1.
https://blog.csdn.net/wkd_007/article/details/140060927

C++作为一种强大的编程语言,其类型转换机制是开发者必须掌握的重要内容。本文将详细介绍C++中自定义类型的类型转换,包括转换构造函数和类型转换运算符的定义、特点、声明、定义和使用方法。通过具体的代码示例和运行结果,帮助读者更好地理解这些概念。

一、概述

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;
    下面是转换构造函数使用的完整例子:定义了三个转换构造函数,可以将
    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个问题:

  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
    对象转换为
    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;
}

运行结果:

四、总结

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

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号