explicit
有一段时间没有写博客,最近一段时间一直在补自己的C++知识,尤其是面向对象的部分。昨晚在看CPP的时候发现了一个有趣的关键字:explicit
在区别explicit的使用之前,请先来简单地了解一下隐式转换和显示转换:
- 隐式转换:在转换的时候不给系统提示具体的模型,让其自动转换,例如:
int a = 10; float b = 12.7; b = a; ---- 这是把int类型转换为了float类型,由编译器自动完成的
- 显示转换:类似于强制转换,例如:
int a = 10; float b = (float) a; ---- 这是把int类型的强制转换成float类型的
- 当类构造函数的参数只有一个的时候,或者所有参数都有默认值的情况下,类A的对象时可以直接被对应的内置类型隐式转换后去赋值的,这样会造成错误
看一个类构造的隐式换元的例子:
#include <iOStream>
using namespace std;
class A
{
public:
// 这个A类的构造函数是可以使用隐式转换的,可以将传递的int类型进行构造
A(int num) : number(num){}
void Show() const{
cout << number << endl;
}
private:
int number;
};
void Func(const A& a){
a.Show();
}
int main(int argc, char const *argv[])
{
Func(119);
return 0;
}
// 输出:119
// 可以看到:虽然在调用Func()函数的时候没有传递A类型的实例,但是仍然打印除了119
// 说明编译器自动进行了隐式转换
explicit 主要使用在类的构造函数前面起修饰作用,作用是禁止类构造函数的隐式换元
不使用explicit的情况:
// explicit - 阻止编译器使用这个构造函数做隐式转换
// ***不使用explicit的情况***
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
// 这两个构造函数的参数不一样
Person(string str) : name(str){}
Person(int _age) : age(_age){
name = string(age, 'x');
}
~Person(){};
void ShowStr() const{
cout << name << endl;
}
private:
string name;
int age;
};
// 定义一个执行函数 - 作用是创建一个打印一个Person对象的name,形式参数需要传递一个Person对
void printPersonName(const Person& p){
p.ShowStr();
}
int main(int argc, char const *argv[])
{
// 此时直接调用一个PrintPersonName函数 - 注意!传递的是一个int类型,按照正常参数传递来说是不正确的!!
PrintPersonName(46);
return 0;
}
输出:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 可以看到:即使是错误的参数,仍然因为隐式转换的原因产生了正确的结果,这样不利于程序错误的排查
// 当类构造函数的参数只有一个的时候,或者所有参数都有默认值的情况下,类A的对象时可以直接被对应的内置类型隐式转换后去赋值的,这样会造成错误
使用explicit的情况:
// ***使用explicit的情况***
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
// 这两个构造函数的参数不一样
explicit Person(string str):name(str){}
explicit Person(int _age):age(_age){
name = string(age, 'x');
}
~Person(){};
void ShowStr() const{
cout << name << endl;
}
private:
string name;
int age;
};
// 定义一个执行函数 - 作用是创建一个打印一个Person对象的name,形式参数需要传递一个Person对
void PrintPersonName(const Person& p){
p.ShowStr();
}
int main(int argc, char const *argv[])
{
// 此时直接调用一个PrintPersonName函数 - 注意!传递的是一个int类型,按照正常参数传递来说是不正确的!!
PrintPersonName(46);
return 0;
}
// 输出: invalid initialiation of reference of type 'const Person&' from expression of type 'int'
// in passing argument 1 of 'void PrintPersonName(const Person&)'
// 此时会报错,因为在使用了explicit关键字之后,禁止了编译器在使用构造函数的时候自动进行隐式转换
// explicit可以抑制内置类型隐式转换,所以在类的构造函数中,最好尽可能多用explicit关键字,防止不必要的隐式转换
参考:
https://blog.csdn.net/qq_36038987/article/details/77029044
https://blog.csdn.net/ftell/article/details/80418678
https://blog.csdn.net/qq_37233607/article/details/79051075
相关阅读
指向引用的指针 使用指针的一个简单例子就是:int v = 1; int *p = &v; 需要预先强调的是没有指向引用的指针!因为引用不是对象,没
strncpy函数介绍 1:strncpy是 C语言的库函数之一,来自 C语言标准库,定义于 string.h,char *strncpy(char *dest, const char *src, i
C++中strncpy函数和strncpy_s函数的使用及注意事项
在掌握了strcpy函数和strcpy_s函数之后,我们不可避免地会谈到strncpy函数和strncpy_s函数,其实这四个函数的功能几乎一致,就是对两个
文章转自: http://www.cnblogs.com/lxshanye/archive/2013/05/20/3088558.html 版权归原作者。 1.变长一维数组 这里说的变长
C++的static有两种用法:面向过程程序设计中的static和面向对象程序设计中的static。前者应用于普通变量和函数,不涉及类;后者主要说