一、explicit
(显式)关键字介绍
在C++
中,我们有时可以将构造函数用作自动类型转换函数。但这种自动特性并非总是合乎要求的,有时会导致意外的类型转换,因此,C++
新增了关键字explicit
,用于关闭这种自动特性。即被explicit
关键字修饰的类构造函数,不能进行自动地隐式类型转换,只能显式地进行类型转换。
注意:只有一个参数的构造函数,或者构造函数有n个参数,但有n-1个参数提供了默认值,这样的情况才能进行自动地隐式类型转换。
在C++中, 一个参数(或虽然有多个参数,但只有1个参数没有默认值)的构造函数, 承担了两个作用:
- 1、发挥普通构造函数功能
- 2、默认且隐含的类型转换操作符
二、配合代码辅助理解
显式声明的构造函数和隐式声明的有什么区别呢? 我们来看下面的例子:
#include <iostream>
using namespace std;class Test1
{
public :Test1(int num) // 显式声明的构造函数{
n = num;}
private:int n;
};class Test2
{
public :explicit Test2(int num) // 隐式声明的构造函数{
n = num;}
private:int n;
};int main()
{
Test1 t1(12); // OK:直接初始化Test1 t2 = 12; // OK:复制初始化Test2 t3(13); // OK:直接初始化Test2 t4 = 13; // 错误:被 explicit 修饰构造函数的对象不可以复制初始化return 0;
}
上面的代码中,"Test1 t2 = 12;
" 这句为什么是可以的呢?
在C++中,如果的构造函数只有一个参数(或虽然有多个参数,但只有1个参数没有默认值)时,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象。也就是说 “Test1 t2 = 12;
” 这段代码, 编译器自动将整型转换为Test1
类对象, 实际上等同于下面的操作:
Test1 t2(12);
或
Test1 temp(12);
Test1 t2 = temp;
运行该程序,会发现在Test2 t4 = 13;
报错,具体报错信息如下:
error: conversion from 'int' to non-scalar type 'Test2' requested
当注释掉Test2 t4 = 13;
,便又可编译成功!这也充分说明加入explicit
关键字后是禁止隐式转换的!
参考
- explicit(显式)关键字那些事
- C++中explicit关键字的使用
- C++ explicit关键字详解