C++转换函数

23 篇文章 22 订阅

一、conversion function, 转换函数

转换函数(conversion function)是一种特殊类型的类成员函数。它定义了一个由用户定义的转换,以便把一个类对象转换成某种其他的类型。
在类的声明中,通过指定关键字operator,并在其后加上转换的目标类型后,我们就可以声明转换函数。

1. 特点

转换函数采用如下的一般形式:
operator type()
这里的type可用内置类型、类类型或typedef名取代。但是不允许type表示数组或函数。
转换函数必须是成员函数,它的声明不能指定返回类型和参数列表。
如果转换函数没有类成员进行修改,可以在函数声明中增加const关键字,增加代码的健壮性。

2. 例子

以下代码展示了类Fraction中的转换函数operator double() const

class Fraction {
public:
    Fraction(int num, int den) :
        m_numerator(num), m_denominator(den) {}

    operator double() const {
        return (double) (m_numerator / m_denominator);
    }

private:
    int m_numerator;  // 分子
    int m_denominator;  // 分母
};

Fraction f(3, 5);
double d = 4 + f;  // 调用operater double将f转换成double

3. 说明

double d = 4 + f;这一语句会首先查找Fraction是否有重载操作符 operator + (double, Fraction) 的函数,由于没有,所以调用会转换函数operator double() const

另外,转换函数除了可以将一个类型转换成另一个基本类型,还可以将一个类型转换成另一个复合类型(例如string类型)。

4. 作用

把这种东西(A)转换成别的东西(B)

二、non-explicit-one-argument constructor

1. 例子

class Fraction 
{
    Fraction(int num, int den=1) :
        m_numerator(num), m_denominator(den) {}

    Fraction operator + (const Fraction& f) {
        return Fraction(...);
    }

private:
    int m_numerator;  // 分子
    int m_denominator;  // 分母
};

Fraction f(3, 5);
Fraction d2 = f + 4;  // 调用non-explicit ctor将4转换成Fraction(4, 1),然后再调用operator +

2. 说明

构造函数虽然有two parameters(两个形参),但只有one argument,且构造函数前面没有explicit,所以叫做non-explicit-one-argument constructor。

3. 作用

把别的东西(B)转换成这种东西(A)

三、conversion function vs. non-explicit-one-argument constructor

1. 例子

class Fraction 
{
    Fraction(int num, int den=1) :
        m_numerator(num), m_denominator(den) {}

    operator double() const {
        return (double) (m_numerator / m_denominator);
    }

    Fraction operator + (const Fraction& f) {
        return Fraction(...);
    }

private:
    int m_numerator;  // 分子
    int m_denominator;  // 分母
};

Fraction f(3, 5);
Fraction d2 = f + 4;  // [Error] ambiguous

2. 说明

上述的代码会导致二义性的出现,即
- 可以将4转换成Fraction
- 可以将f转换成double,与4相加得到一个double,然后再转换成Fraction

为了使得编译通过,可以将Fraction d2 = f + 4;改成double d2 = f + 4;即可。

四、explicit-one-argument constructor

1. 例子

class Fraction 
{
    explicit Fraction(int num, int den=1) :
        m_numerator(num), m_denominator(den) {}

    operator double() const {
        return (double) (m_numerator / m_denominator);
    }

    Fraction operator + (const Fraction& f) {
        return Fraction(...);
    }

private:
    int m_numerator;  // 分子
    int m_denominator;  // 分母
};

Fraction f(3, 5);
Fraction d2 = f + 4;  // [Error] convertion from double to Fraction requested

2. 说明

由于在构造函数前面增加了explicit关键字,所以不能将4转换成Fraction类型;也不能先将f转换成double类型,与4相加后再将double转换成Fraction。

3. 作用

explicit这个关键字基本只出现在构造函数前面,意思是需要明确地需要调用这个构造函数才能调用,不存在暗中、自动的转换操作。

五、转换函数在STL中的运用

1. 例子

template<class Alloc>
class vector<bool, Alloc>
{
public:
    typedef __bit_reference reference;

protected:
    reference operator[] (size_type n) {
        return *(begin() + defference_type(n));
    }
};

struct __bit_reference {
    unsigned int *p;
    unsigned int mask;

public:
    operator bool() const {
        return ! ( ! ( *p & mask) ); 
    }
};

2. 说明

class vector <bool, Alloc>这里是模板的偏特化。

reference operator[] (size_type n)返回vector元素的类型,从vector类型的声明看,应该是返回 一个bool类型的值,可是现在却返回了一个referecnce类型。
reference类型亦即__bit_reference类型,故__bit_reference类型需要转换成bool类型。
这样就要求__bit_reference类型需包含一个转换函数,可以将__bit_reference类型转换成bool类型,这正是转换函数operator bool() const的作用。

参考资料

  1. 侯捷《C++最佳编程实践》视频,极客班,2015
  2. 《C++ Primer》中文版,第三版,潘爱民等译,2002
  • 10
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值