隐式转换与explicit关键字
隐式转换
函数构造的隐式转换,直接上代码:
#include<bits/stdc++.h>
class Entity {
private:
std::string m_Name;
int m_Age;
public:
Entity(const std::string& name)
: m_Name(name), m_Age(-1) {}
Entity(int age)
:m_Name("Unknown"), m_Age(age) {}
};
void printEntity(Entity e) {
// some code to print entity
// ...
}
int main() {
printEntity(18);
printEntity("OrzMiku");
}
我有一个 Entity
类,有两个私有成员变量 string类 m_Name
和 int类型 m_Age
用来表示名称和年龄。
接着有两个不同版本的构造函数,注意,这两个构造函数都有且只有一个参数传入。这里重点mark一下
然后有一个打印实体的函数 printEntity
,这个函数需要一个 Entity
类作为参数。
正常来说,我们可以这样调用这个函数:
printEntity(Entity(22));
printEntity(Entity("OrzMiku"));
这里有一个常见的隐式转换,是将char数组转换成string类。
但是注意上面的代码中,是这样调用这个函数的:
printEntity(18);
printEntity("OrzMiku");
其中,第一句是正确的,第二句是错误的。
第一句中直接传入了一个 int
类型,函数需要一个 Entity
类型,在 Entity
类中有一个构造函数的参数只需要一个int类型,这时就可以发生隐式转换。将 int
作为参数隐式转换成一个 Entity
类型。
第二句中直接传入了一个 char
数组,但是在Entity类中没有构造函数的参数只需要一个 char
数组。虽然有一个构造函数需要一个 string
,但是 char
数组到 string
, string
到 Entity
需要两次转换,所以不能隐式转换。
第二句可以改成这样:
printEntity(std::string("OrzMiku"));
同理,我们在创建Entity实例的时候,也就可以这样:
Entity a = 18;
Entity b = std::string("OrzMiku");
虽然在C++中可以这样写,但是还是推荐不使用这样的隐式转换,虽然有时可以让代码看起来更加简洁,但是我觉得会大大降低代码的可读性
explicit关键字
正如前面所说,不推荐使用隐式转化。explicit关键字就可以禁止隐式转化。
用explicit关键字修饰一个构造函数,就意味着这个构造函数没有隐式转化,必须显式调用这个构造函数。上代码:
#include<bits/stdc++.h>
class Entity {
private:
std::string m_Name;
int m_Age;
public:
Entity(const std::string& name)
: m_Name(name), m_Age(-1) {}
explicit Entity(int age)
:m_Name("Unknown"), m_Age(age) {}
};
void printEntity(Entity e) {
// some code to print entity
// ...
}
int main() {
printEntity(18);
printEntity(std::string("OrzMiku"));
}
还是刚刚那个代码,有一点点小小的改动,我们将Entity的一个构造函数用explicit关键词修饰了。此时底下的 printEntity(18);
这行就报错了。因为不能用explicit修饰了其对应的构造函数,这个构造函数现在必须显式调用了。
所以这句代码写成这样就好了:printEntity(Entity(18);