#include <iostream>
using namespace std;
struct Rational_1 {
Rational_1(int n=0, int d=1) : num(n), den(d) {
cout << __func__ << "(" << num << "/" << den << ")" << endl;
}
int num; //Numerator被除数
int den; //Denominator除数
};
struct Rational_2 {
explicit Rational_2(int n=0, int d=1) : num(n), den(d) {
//加了explicit关键字,代表该构造函数不能被隐式调用,必须显式调用才能运行
cout << __func__ << "(" << num << "/" << den << ")" << endl;
}
int num; //Numerator被除数
int den; //Denominator除数
};
void Display1(Rational_1 ra){
cout << "Numerator: " << ra.num << " Denominator: " << ra.den << endl;
}
void Display2(Rational_2 ra){
cout << "Numerator: " << ra.num << " Denominator: " << ra.den << endl;
}
template <typename T>
class Ptr {
public:
Ptr(T* p) : _p(p) {}
//定义一个从Ptr类型转换成bool类型的函数
explicit operator bool() const {
if (_p != 0)
return true;
else
return false;
}
private:
T* _p;
};
/*************************************************************************
**1. explicit 关键字修饰函数,将会禁止函数被隐式调用
** 有些情况下,函数的隐式调用会导致意想不到的问题出现,
** 经常出现问题的场景有:拷贝构造函数的隐式传递调用 和 非显式的类型转换
*************************************************************************/
class ConvertTo {
public:
ConvertTo() {}
//ConvertTo( const ConvertTo & ) {}
};
class Convertable {
public:
explicit operator ConvertTo () const { return ConvertTo(); } //定义Convertable类型向ConvertTo类型的转换函数
};
void Func(ConvertTo ct) {}
int main()
{
Rational_1 r1_1 = 11; //该表达式理应是调用拷贝赋值函数,但是因为r1_1并无初始化,所以将隐式调用带参构造函数
Rational_1 r1_2(12); //显式调用带参构造函数
//Rational_2 r2_1 = 21; //error: conversion from 'int' to non-scalar type 'Rational_2' requested
Rational_2 r2_2(22); //显式调用带参构造函数,可以编译通过
Display1(1); //参数传递,将隐式调用构造函数
//Display2(2); //无法通过编译,could not convert '2' from 'int' to 'Rational_2'
Display2(Rational_2(2)); //显式调用构造函数传递临时对象
int a;
Ptr<int> p(&a);
if (p)
cout << "valid pointer." <<endl; //valid pointer
else
cout << "invalid pointer." << endl;
Ptr<double> pd(0);
//cout << p+pd << endl; //如果不加explicit修饰Ptr类中的转换函数,则该表达式将会隐式调用
//该转换函数,但是指针量之间的相加并无意义,但是因为转换函数的定义,该表达式将被编译通过
//所以应该给转换函数加上explicit,以避免可能存在不当使用并且难以察觉
//加上explicit修饰转换函数后,则除了在bool量应该出现的位置,是不会调用该转换函数的
//所以编译器将报错:error: no match for 'operator+' (operand types are 'Ptr<int>' and 'Ptr<double>'
Convertable c;
ConvertTo ct(c); //直接初始化,pass
//ConvertTo ct2 = c; //error: conversion from 'Convertable' to non-scalar type 'ConvertTo' requested
ct = static_cast<ConvertTo>(c); //强制类型转化,通过
Func(static_cast<ConvertTo>(c)); //could not convert 'c' from 'Convertable' to 'ConvertTo'
return 0;
}
杂货边角(19):explicit显式类型转换限定符号
最新推荐文章于 2024-02-18 22:05:52 发布