c++类的类型转换函数

之前学习的,可以将普通类型转换为类类型,需要借助转换构造函数。那么反过来,类类型可以转换为普通类型吗?

#include <stdio.h>

class TestCls{
public:
    int a;

    TestCls(int x = 0) : a(x)
    {}
};

int main(void)
{
    TestCls t1;

    int i = t1;

    printf("i = %d\n", i);

    return 0;
}

编译报错:
这里写图片描述

即使加上强制类型转换:

int i = (int)t1;

报错依旧。

一个类类型变量要转换成普通类型,需要借助类的类型转换函数。类型转换函数用于将类对象转换为其它类型,语法规则为:

operator Type()
{
    Type ret;

    //...

    return ret;
}

加入类型转换函数之后:

class TestCls{
public:
    int a;

    TestCls(int x = 5) : a(x)
    {}

    /* 类型转换函数,将TestCls类转换为int类型 */
    operator int()
    {
        return a;
    }

};

int main(void)
{
    TestCls t1;

    int i = t1;

    printf("i = %d\n", i);

    return 0;
}

编译运行:
这里写图片描述

使用类型转换函数需要注意:
1. 类型转换函数必须是成员函数,不能指定其返回类型,并且形参必须为空,返回值是隐含的,返回值类型是和转换的类型Type是相同的,在本例子中为int。
2. Type表示内置类型名、类类型名或者是类型别名(typedef)。除了void外,任何可作为函数返回类型的类型都可以定义转换函数的目标转换类型。一般不允许转换为数组或函数类型,但是可以转换为指针类型以及引用类型
3. 类型转换函数一般不应该改变被转换的对象,因此转换函数通常属性被定义为const。

int i = t1;能够编译运行,因为调用了类型转换t1对象的类型转换函数operator int()。

类型转换函数用于将类对象转换为其它类型,那么就可以实现将A类类型对象转换成B类类型对象:

class A
{
private:
    int a;

public:
    A(int x = 0) : a(x)
    {}

    char value()
    {
        return a;
    }
};

class B
{
private:
    char c;

public:
    B(char y = 0) : c(y)
    {}

    char value()
    {
        return c;
    }
};

int main(void)
{
    A class_a;
    B class_b(100);

    class_a = class_b;

    printf("class_a.a = %d\n", class_a.value());

    return 0;
}

两种不同类型的对象相互赋值,必然报错:
这里写图片描述

B类定义类型转换函数后:

class B
{
private:
    char c;

public:
    B(char y = 0) : c(y)
    {}

    char value()
    {
        return a;
    }

    operator A ()
    {
        A tmp(c);
        return tmp;
    }
};

编译运行正常:
这里写图片描述

class_a = class_b;其实等价于class_a = class_b.operator int();

在前面我们已经尝试通过转换构造函数的方法,同样可以实现将A类类型对象转换成B类类型对象:

class B;        //前向声明

class A
{
private:
    int a;

public:
    A(int x = 0) : a(x)
    {}

    A(B& cB)
    {
    }

    char value()
    {
        return a;
    }
};

class B
{
public:
    char c;

public:
    B(char y = 0) : c(y)
    {}

    char value()
    {
        return c;
    }

    /*operator A ()
    {
        A tmp(c);
        return tmp;
    }*/
};



int main(void)
{
    A class_a;
    B class_b(100);

    class_a = class_b;

    return 0;
}

需要注意,类型转换函数转换的是右值,转换构造函数转换的是左值。

右值的类型转换函数和左值的转换构造函数都可以实现隐式的类型转换,那么如果二者同时存在于代码中,在需要类型转换时,编译器会选择调用谁?

去除代码中的注释编译运行:
这里写图片描述
编译器因不知道该调用谁而报错。

类型转换函数和转换构造函数具有同等地位,编译器同样能够隐式的使用类型转换函数,在实际项目工程中为了代码的可控性,程序员一般不会使用编译器这个隐式转换功能。explicit关键字可去除转换构造函数的隐式调用,那类型转换函数呢?换个函数名即可,通常函数名为”TypetoTpye()”:

class B
{
public:
    char c;

public:
    B(char y = 0) : c(y)
    {}

    char value()
    {
        return c;
    }

    A toA ()
    {
        A tmp(c);
        return tmp;
    }
};

int main(void)
{
    A class_a;
    B class_b(100);

    class_a = class_b.toA();

    printf("class_a.a = %d\n", class_a.value());

    return 0;
}

事实上,很多成熟的类库都是这么实现的,如STL、QT等。

  • 12
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值