C++类的自动类型转换和强制类型转换

类型转换

我们都知道C++ 会自动处理内置类型的转换。例如,将一个标准类型变量的值赋给另一种标准类型的变量时,如果这两种类型兼容,则C++ 自动将这个值转换为接收变量的类型。

long a = 8;     // int类型自动转换成long类型
double b = 11;  // int类型自动转换成double类型
int c = 3.14;   // double类型自动转换成int类型,但是会降低精度,变为3
int *p = 10;    // 报错,无法自动转换,左边是指针类型,右边是整数,类型不兼容
int *p = (int *)10;     // 正确,将10强制转换为int指针类型,将指针设置为地址10

类的自动类型转换

可以将类定义成与基本类型或另一个类相关,使得从一种类型转换为另一个种类型。

实例一

#include <iostream>
using namespace std;

class Test
{
    private:
        double m_sum;
    public:
        Test()  // 默认构造函数
        {
            m_sum = 0;
        }
        Test(double sum)  // 构造函数
        {
            m_sum = sum;
        }
        ~Test(){}       // 析构函数
        Test operator+(const Test &t) const;    // 重载加法运算符
        friend ostream& operator<<(ostream &os, const Test &t);
};
void DisplayTest(const Test &t)
{
    cout << t << endl;
}
int main()
{
    Test t1(100.1);
    Test t2 = 200.2;         // double类型的值转换为Test类型
    Test t3 = t2 + 100.1;    // 100.1自动转换为Test的对象

    cout << "t1: " << t1 << endl;
    cout << "t2: " << t2 << endl;
    cout << "t3: " << t3 << endl;
    DisplayTest(t1);
    DisplayTest(400.4);     // 隐式转换
    DisplayTest(300);       // int类型先转换为double,然后在转换为Test类型
    return 0;
}
Test Test::operator+(const Test &t) const
{
    Test temp;
    temp.m_sum = this->m_sum + t.m_sum;
    return temp;
}
ostream& operator<<(ostream &os, const Test &t)
{
    os << t.m_sum;
    return os;
}

程序说明

Test类提供了一个接受double类型的构造函数。可以用于将double类型的值转换为Test类型。

Test(double sum);

因此,有这样合法的代码

Test t1(100.1);
Test t2 = 200.2;
Test t3 = t2 + 100.1;
DisplayTest(400.4);
DisplayTest(300);

程序将使用构造函数Test(double sum)来创建一个临时的Test对象,并将200.2作为初始值。然后赋值给t2。这一过程称为隐式转换。

同理,在调用DisplayTest(400.4)时,先将400.4转换为一个临时的Test对象,然后赋值给DisplayTest(const Test &t)函数。

如果传递一个int类型的变量: DisplayTest(300); 编译器会先将int类型转换为double类型,再调用Test(double)将其转换为Test对象。

关闭隐式转换

可以在构造函数前加上关键字explicit关闭隐式转换。

explicit Test(double sum);     // 关闭隐式转换

Test t2 = 200.2;        // 非法,无法进行隐式转换
Test t3 = t2 + 100.1;   // 非法,无法进行隐式转换
DisplayTest(400.4);     // 非法,无线进行隐式转换

Test t4 = (Test)200.2;      // 合法,显示强制类型转换
Test t5 = t4 + (Test)100.1; // 合法,显示强制类型转换
DisplayTest((Test)400.4);   // 合法,显示强制类型转换

如果使用了关键字explicit限定了构造函数,则它只能用于显示转换。

转换函数

转换函数用于将自定义类型转换为内置类型。

语法

operator typeName();

typeName是要转换的类型

例如

operator double();  // 要转换为double类型

注意

  • 转换函数必须是类方法;
  • 转换函数不能指定返回类型;
  • 转换函数不能有参数。

实例二

#include <iostream>
using namespace std;

class Test
{
    private:
        double m_sum;
    public:
        Test()  // 默认构造函数
        {
            m_sum = 0;
        }
        Test(double sum)  // 构造函数
        {
            m_sum = sum;
        }
        ~Test(){}       // 析构函数
        Test operator+(const Test &t) const;    // 重载加法运算符
        operator double() const;
        operator int() const;
};
int main()
{
    Test t1(100.1);
    Test t2 = 200.2; 
    // Test t3 = t2 + 100.1; // 同时重载了加法运算符和定义了转换函数,隐式转换会产生二义性,所以需要显示转换
    Test t3 = t2 + (Test)100.1; // 需要显示转换

    cout << "t1: " << (double)t1 << endl;   // 调用转换函数,operator double() const
    cout << "t2: " << (double)t2 << endl;   // 调用转换函数,operator double() const
    cout << "t3: " << (int)t3 << endl;      // 调用转换函数,operator int() const

    int a = t1;     // 调用转换函数,operator int() const
    double b = t2;  // 调用转换函数,operator double() const
    cout << "a: " << a << endl;
    cout << "b: " << b << endl;
    return 0;
}
Test Test::operator+(const Test &t) const
{
    Test temp;
    temp.m_sum = this->m_sum + t.m_sum;
    return temp;
}

Test::operator int() const
{
    return (int)m_sum;
}

Test::operator double() const
{
    return m_sum;
}

程序说明

  1. 没有重载<<运算符进行显示。
  2. 使用重载的+运算符时,需要显示转换。

注意

如果同时重载了加法运算符和定义了转换函数,隐式转换会产生二义性,所以需要显示转换。

Test t3 = t2 + 100.1;   // 隐式转换,产生二义性
Test t3 = t2 + (Test)100.1;     // 显示转换
Test t3 = (double)t2 + 100.1;   // 显示转换
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值