显式关键字在C++中的工作与实例

461 阅读4分钟

C++ explicit

C++显式简介

在C++中,显式是用于构造函数前的一个关键字,其定义是通过指定关键字显式使构造函数不进行任何隐式转换。这样定义是为了避免当一个类包含一个单参数的构造函数时出现少数隐式转换,通常编译器会认为它是一个转换构造函数或隐式转换,这又可能导致一些不需要的输出,为了避免这样的结果,我们必须在构造函数名称前用显式关键字来定义这种构造函数。一般来说,显式构造函数是在我们不能使用隐式构造函数的地方声明的,这种显式构造函数总是有单个或多个参数。

显式关键字在C++中的工作与实例

在这篇文章中,我们将看到显式关键字用于不能使用隐式构造器的构造器。在C++中,我们知道构造函数主要用于初始化或创建类的对象,这些对象是由编译器默认提供的,我们可以使用这样的构造函数进行类型转换,如与类声明中的构造函数进行隐式或显式转换。这个显式关键字是可选的,它总是只需要一个参数,这样的构造函数可以用于类型转换。

如果隐式转换是不可控的,那么我们需要用显式声明的关键字为类声明内的构造函数指定这样的构造函数,但是我们应该注意一点,我们不能对默认构造函数使用这个显式关键字。一般来说,我们可以说,在类声明中为有单个或多个参数的构造函数指定显式关键字,是为了防止类出现不必要的类型转换;否则,如果没有这个显式关键字,它将是一个转换的构造函数。

让我们来看看下面的例子,为什么要在C++中使用显式关键字,以及在哪里使用。

例子 #1

代码

#include <iostream>
using namespace std;
class Edu{
char var_c;
public:
Edu() {}
Edu(char c): var_c(c) {};
void print() {std::cout << "The value is "<< var_c <<endl;}
};
void disp(Edu u)
{
u.print();
}
int main()
{
Edu ins('E');
Edu ins1 = 'D';
cout<<"Below value is obtained when constructor is called normally :" << endl;
disp(ins);
cout<<"\n" <<endl;
cout<<"Below value is obtained when compiler implicitly is called to convert it to char type from Edu type is : " << endl;
disp(ins1);
return 0;
}

输出

c++ explicit 1

在上面的程序中。我们可以看到,首先我们声明了一个类 "Edu",我们声明了一个字符类型的变量var_c,我们创建了一个默认的构造函数,参数为0,另一个构造函数为类名,参数为char类型的变量c,我们正在打印传递给这个函数的值,我们必须记住,我们必须只传递char类型的值,但是我们可以看到在main()函数中,我们创建了第一个类Edu对象 "ins",我们将 "E "字母传递给disp()函数,这个函数有一个参数为Edu类型,因此它将打印这个值,因为它正常调用构造函数但是当我们创建了另一个Edu类的对象 "ins1",并且在disp()函数中我们传递了 "Edu "类型的参数,所以当我们现在调用disp()函数并试图将char类型的 "D "字母分配给这个 "Edu "类型的ins1对象时,编译器将隐含地将这个 "Edu "类型的变量转换为char类型的变量,它给出的输出是char值,如上面的截图所示,这有时是不正确的,所以为了避免这种隐含的调用,我们必须在有单个参数的构造函数中添加 "explicit "关键字,如 "explicit Edu(char c):var_c(c) {};" 所以当我们改变上述代码时,我们会得到如下截图中的错误。

compilation failed

所以这里是输出结果;我们可以看到从char类型到Edu的转换是非标量的,这不是一个合法的调用,所以在这种情况下,或者在有机会进行隐式构造函数转换的地方,使用显式关键字是一个好的做法。所以在上面的代码中,我们为有一个char类型参数的 "Edu "构造函数编写了关键字 "explicit"。

现在让我们看一个有两个参数的例子;我们将看到显式在双参数构造函数中是否有效。

例子 #2

代码

#include <iostream>
using namespace std;
class Edu
{
private:
int i;
int j;
public:
Edu(int a = 0, int b = 0) : i(a), j(b) {}
bool operator== (Edu e) {
return (i == e.i && j == e.j)? false : true;
}
};
int main()
{
Edu ins(3, 4);
cout << "It will print matched if the given values match else not same which uses implicit call to convert int to Edu type:" <<endl;
cout<< "\n" <<endl;
if (ins == 3)
cout << "matched";
else
cout << "No match";
return 0;
}

输出

works with a two-argument constructor

在上面的程序中,我们可以看到这也是和上面一样的代码,但是我们在构造函数中使用了两个参数。通常,当只有一个参数的构造函数时,应用或使用显式是最好的做法,因为两个或多个参数的构造函数可能会导致在主函数中调用它们时的混乱。所以在上面的例子中,它的工作原理也是如此,构造函数被编译器隐式调用,而这并不是合法或正确的获取输出的形式。所以为了避免这种可能产生输出的不理想的程序执行,从逻辑上讲,转换类型是不正确的,所以我们对构造函数使用显式关键字。在上面的代码中,我们也可以在类内声明构造函数之前用显式关键字重写代码,如 "explicit Edu(int a = 0, int b = 0): i(a), j(b) {}",这样输出就会像下面的截图。

c++ explicit 4

总结

在这篇文章中,我们可以得出结论,在C++中,显式关键字通常用于在类声明中创建类对象的构造函数。在这篇文章中,我们看到显式关键字只用于构造函数,当我们想避免编译器的隐式调用时,编译器通常将构造函数作为转换构造函数,将变量从一种类型转换为另一种类型,这样做是不正确或不合法的。在这种情况下,最好的做法是始终使用显式关键字,因为它将给出一个错误,说那里有非标量类型;我们已经在上面的文章中看到了例子。