[C++11阅读][2-3-1]显式类型转换

2020-05-30  本文已影响0人  凌霄阁2010

避免已知类型向自定义类型隐式转换

explicit关键字加在构造函数前面,可以声明此函数应当被显式调用,而不是在隐式类型转换时被隐式调用。

#include <iostream>
using namespace std;
struct Rational1 {
    Rational1(int n=0, int d=1): num(n), den(d) {
        cout << __func__ << "(" << num << "/" << den << ")" << endl;
    }
    int num;
    int den;
};
struct Rational2 {
    explicit Rational2(int n=0, int d=1): num(n), den(d) {
        cout << __func__ << "(" << num << "/" << den << ")" << endl;
    }
    int num;
    int den;
};
void Display1(Rational1 ra) {
    cout << "Numerator: " << ra.num << " Denominator: " << ra.den << endl;
}
void Display2(Rational2 ra) {
    cout << "Numerator: " << ra.num << " Denominator: " << ra.den << endl;
}
int main() {
    Rational1 r1_1 = 11;  // OK
    Rational1 r1_2(12);  // OK
    Rational2 r2_1 = 21;  // error: conversion from ‘int’ to non-scalar type ‘Rational2’ requested
    Rational1 r2_2(22);  // OK
    Display1(1);  // OK
    Display2(2);  // 隐式构造 error: could not convert ‘2’ from ‘int’ to ‘Rational2’
    Display2(Rational2(2));  // 显式构造 OK
    return 0;
}

避免自定义类型向已知类型隐式转换

上一小节的例子可以避免已知类型(int)向自定义类型(Rational2)的隐式转换,但没对自定义类型向已知类型转换进行限制。
explicit关键字加在类型转换操作符重载前面,可以做到以上限制。
留意下类型转换操作符的写法,operator 类型() {},比如operator bool() {},这里的bool不是返回值类型,而是与括号连用组成强制类型转换符。

#include <iostream>
using namespace std;
class ConvertTo {};
class Convertable {
public:
    explicit operator ConvertTo() const {
        return ConvertTo();
    }
};
void Func(ConvertTo ct) {}
void test() {
    Convertable c;
    ConvertTo ct(c);  // 直接初始化 OK
    ConvertTo ct2 = c;  // 拷贝构造时隐式类型转换 error: conversion from ‘Convertable’ to non-scalar type ‘ConvertTo’ requested
    ConvertTo ct3 = static_cast<ConvertTo>(c);  // 显式强制类型转换 OK
    Func(c);  // 传参时隐式类型转换 error: could not convert ‘c’ from ‘Convertable’ to ‘ConvertTo’
}

小结

explicit不是禁止从源类型到目标类型的转换,而是限定了所修饰函数必须显式调用,如果所修时函数是构造函数和类型转换操作符,达成了显示类型转换这一效果。

上一篇 下一篇

猜你喜欢

热点阅读