目录
用explicit关键字避免类的隐式转换
概念:对于类来说什么是隐式转换?
我们常常用初始化表法来初始化类成员,初始化表的实质是调用类的构造函数,将初始化表中的元素进行隐式转换为类所能接受的类型。
代码示例
初始化的表的隐式转换
#include <iostream>
using namespace std;
class Cstudent
{
private:
string name;
int age;
public:
// 避免使用构造函数进行隐式转换
Cstudent(string name, int age)
{
this->name = name;
this->age = age;
}
~Cstudent()
{
cout << "调用析构函数" << endl;
}
};
int main()
{
// 没加explicit的话,就可以用用初始化表进行隐式转换并初始化类对象
Cstudent stud = { "超级霸霸强",19 };
}
初始化表的显式转换
#include <iostream>
using namespace std;
class Cstudent
{
private:
string name;
int age;
public:
// 避免使用构造函数进行隐式转换
explicit Cstudent(string name, int age)
{
this->name = name;
this->age = age;
}
~Cstudent()
{
cout << "调用析构函数" << endl;
}
};
int main()
{
// 加了explicit之后,我们可以用显式转换来初始化类成员,以下两种方式均可
Cstudent stud{ "超级霸霸强",19 };
Cstudent stud1 = Cstudent{ "超级霸霸强",19 };
}
用explicit避免重载类型转换操作符后所产生的隐式转换
概念
类型转换操作符的重载无疑是给类的类型转换提供了更多的人性化的方式,类的类型转换符必须遵守以下几点:
① 类的数据类型转换结果一定符合类型转换符的形式,例如const char*代表这个类强制转换后的结果一定是返回字符型的指针变量;
② 在类中重载类型转换符时,不需要加参数和返回值类型,因为类中所有函数都默认传入一个this指针作为默认形参,而且类型转换符是单目运算符,这意味着它只需一个操作对象因此无需返回值。
代码示例
#include <iostream>
#include <sstream>
#include <string>
using namespace std;
class Data
{
private:
int year;
int month;
int day;
string RecordInf;
public:
Data(int year, int month, int day)
{
this->year = year;
this->month = month;
this->day = day;
}
~Data()
{
cout << "调用析构函数" << endl;
}
// 用关键字避免类型转换中的隐式转换
explicit operator const char* () // 单目运算符重载不需要加参数和返回值类型,因为类型转换改变的是编译器对于变量的解释方式,并不是变量本身
{
ostringstream output;
output << this->year << "/" << this->month << "/" << this->day << endl;
RecordInf = output.str(); // str()是字符串输入输出流的函数,用于返回一个字符串
return RecordInf.c_str(); // c_str()是string中的函数,可以返回字符串的指针
}
// 切记:一定要返回cout可以接受的类型,否则cout无法识别,进而导致无法正常的输出
};
int main()
{
Data data = { 2020,7,14 };
// 这里我们重载的类型转换符返回的是字符串地址,因为类型转换中要求转换为char型的指针
cout << (const char*) data << endl;
//cout << data << endl; // 进行了隐式转换
}