详解 c++ 关键字 explicit

article/2025/9/17 21:38:53

    用了很久的C++ 了,今天突然被小伙伴问道,构造函数前的explicit 关键字什么作用,于是自己也只能支支吾吾的说出“为了显式调用……”很尴尬啊……典型的知道所以然不知道其所以然……好吧,搜搜资料好好地充充电……

    首先说定义,C++ 中的explicit关键字只能用于修饰只有一个参数的类构造函数,它的作用是表明该构造函数是显式的,而非隐式的。跟他对应的另一个关键字是implicit,意思是隐藏的,类构造函数默认情况下就是声明为implicit(隐式的)。

这里的重点就是 只能 修饰 只有一个参数的 类的构造函数。也就是说,

一、只可以修饰类的构造函数,一般的函数不能修饰。

二、只有类的构造函数有一个参数时候,才有效,当有多个参数时候就没什么意义了(这里有个例外,就是当除了第一个参数以外的其他参数都有默认值的时候,explicit依然有效,此时调用构造函数时只传入一个参数,等效于只有一个参数的类构造函数)。

我们先来看看什么是显式调用,什么是隐式调用:

class MyClass   //没有使用explicit关键词,默认为隐式声明
{
public:int m_size;char *m_pStr;MyClass(int size)                        //没有使用explicit关键词,默认为隐式声明{m_size = size;                        //大小m_pStr = (char *)malloc(size + 1);    //给m_pstr 分配size的大小的内存memset(m_pStr, 0, size + 1);}MyClass(const char *pStr)                //没有使用explicit关键词,默认为隐式声明{m_size = strlen(pStr);m_pStr = (char *)malloc(m_size + 1);  //给m_pstr分配内存strcpy(m_pStr, pStr);                //复制内容}MyClass(int size, const char *pStr)    //参数为两个,所以不管是否使用explicit关键字,都是无效的。{m_size = size;int size1 = strlen(pStr);    //大小m_pStr = (char *)malloc(size1 + 1);  //给m_pstr分配内存strcpy(m_pStr, pStr);}};

下面是调用:


    MyClass c1(10);         // ok, 显式调用 MyClass(int size)MyClass c2 = 12;        // ok, 隐式调用 MyClass(int size)MyClass c3;             // 错误, 没有响应的构造函数MyClass c4("hello");    // ok, 显式调用 MyClass(const char *pStr)MyClass c5 = "nihao";   // ok, 隐式调用MyClass c6(5, "hello"); // ok, 显式调用 MyClass(int size, const char *pStr)c1 = 5;                 // ok, 隐式调用 MyClass(int size)c2 = 6;                 // ok, 隐式调用 MyClass(int size)c4 = "hello world";     // ok, 隐式调用 MyClass(const char *pStr)c3 = c1;                // 错误, 编译是没问题的,但是必须在类里重载“=”运算符才行

    上面代码 c2 = 12; c5 = "nihao"为什么是可以的呢?

    因为在C++中,如果构造函只有一个参数时,那么编译的时候就会有一个缺省的转换操作:将该构造函数对应的数据类型的数据转换为该类对象。

    也就是说MyClass c2 = 12;等同于MyClass c2(12);

    但是上面的代码中的MyClass c2(12),中12表示分配内存大小,那么c2 = 12 与5 = "nihao"这样的隐式转换显得不伦不类,容易被误解,怎么避免使用这样的隐式转换呢?答案就是使用关键字explicit,我们将类中的构造函数添加上explicit关键字试试:

class MyClass
{
public:int m_size;char *m_pStr;explicit MyClass(int size){m_size = size;                //大小m_pStr = (char *)malloc(size + 1);    //给m_pstr 分配size的大小的内存memset(m_pStr, 0, size + 1);}explicit MyClass(const char *pStr){m_size = strlen(pStr);m_pStr = (char *)malloc(m_size + 1);  //给m_pstr分配内存strcpy(m_pStr, pStr);         //复制内容}explicit MyClass(int size, const char *pStr)        //两个参数,所以添加explicit是无效的。{m_size = size;int size1 = strlen(pStr);    //大小m_pStr = (char *)malloc(size1 + 1);  //给m_pstr分配内存strcpy(m_pStr, pStr);}};

再次编译一下结果如下:


    

    发现隐式调用的全部错误,这就是使用关键字explicit,显式调用的效果。也就是说,关键字explicit的作用就是防止够咱函数的隐式转换。

    上面也说过了,explicit关键字只对有一个参数的类构造函数有效,如果函数的参数大于或者等于两个时候,是不会产生隐式转换的,所以explicit也就是无效的。一个例外就是,当除了第一个参数意外其他参数都有默认值的时候,explicit关键字依然有效,此时当调用构造函数时,只传入一个参数,等同于只有一个参数的类构造函数。

  explicit MyClass(int size, const char *pStr = "hello"){m_size = size;int size1 = strlen(pStr);    //大小m_pStr = (char *)malloc(size1 + 1);  //给m_pstr分配内存strcpy(m_pStr, pStr);}

上面这种情况,explicit也是有效的!


http://chatgpt.dhexx.cn/article/00KF8fBZ.shtml

相关文章

explicit的用法

explicit的用法 explicit关键字的作用是:禁止隐式调用类的单参数构造函数,主要禁用以下两种操作: 禁止隐式调用拷贝构造函数 禁止类对象之间的隐式转换 类对象之间的隐式转换是指利用一个已经存在的其它类型的对象来创建本类的新对象&#…

C++中的explicit关键字介绍

C中的关键字explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。类构造函数默认情况下声明为隐式的即implicit。 隐式转换即是可以由单个实参来调用的构造函数定义了一个从…

C++中explicit的作用及用法

仅含一个参数的构造函数和除了第一个参数外其余参数都有默认值的多参构造函数承担了两个角色。 1. 是个构造函数;2 .是个默认且隐含的类型转换操作符。 explicit是个C关键字,其作用是指定仅有一个参数或除第一个参数外其它参数均有默认值的类构造函数…

C++ explicit

C提供了关键字explicit,声明为explicit的构造函数不能在隐式转换中使用。 1)C的类型转换分为两种,一种为隐式转换,另一种为显式转换。 2)C中应该尽量不要使用转换,尽量使用显式转换来代替隐式转换。 1隐式转换 定义&#xff1a…

C++ 中explicit的作用及用法(虽然简单,但是还是有用的)

目录 Cexplicit(官网的说法) explicit specifier Cexplicit 清楚的说法(建议英文不好的从这里开始食用哦) explicit作用: explicit使用注意事项: Cexplicit使用的例子(建议喜欢自己敲代码实验的从这里开始食用哦&…

C++之explicit的作用介绍

1、C中的关键字explicit主要是用来修饰类的构造函数,被修饰的构造函数的类,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。类构造函数默认情况下声明为隐式的即implicit。隐式转换即是可以由单个实参来调用的构造函数定义了一个…

explicit关键字详解

在C中,explicit关键字用来修饰类的构造函数,被explicit修饰的类的构造函数,不能发生相应的隐式类型转换,只能以显示的方式进行类型转换。 explicit使用注意事项: explicit 关键字只能用于类内部的构造函数声明上。 explicit 关…

74HC244;74HCT244——三态八路缓冲器/线路驱动器

1.特点: 2.引脚及封装: 3.引脚定义: 解释: output enable input (active LOW)输出使能,低电平有效 data input:数据输入 bus output:总线输出 4.使用逻辑: 解释: L:…

三态门(三态缓冲器)的工作原理

转载于http://www.eeworld.com.cn/mcu/article_2017102035218.html 为减少信息传输线的数目,大多数计算机中的信息传输线均采用总线形式,即凡要传输的同类信息都走同一组传输线,且信息是分时传送的。在计算机中一般有三组总线,即数…

2021-05-18

TTL集成门电路——三态门(与非门) 1、三态门的三种输出状态:高电平(逻辑1),低电平(逻辑0),高阻态(电阻大,可以视为开路) 2、三态门真值表及逻辑符号: !3、三态门的工作电路: 4、三态门的工作原理: EN为三…

锁存器、触发器、寄存器和缓冲器的区别

目录 一、锁存器 二、触发器 三、寄存器 四、移位寄存器 五、总线收发器/缓冲器 六、锁存器与触发器的区别 七、D触发器和D锁存器的区别 八、寄存器与锁存器的区别 一、锁存器 锁存器(latch)---对脉冲电平敏感,在时钟脉冲的电平作用…

三态门与高阻态

转自:https://blog.csdn.net/lin200753/article/list/4 高阻态这是一个数字电路里常见的术语,指的是电路的一种输出状态,既不是高电平也不是低电平,如果高阻态再输入下一级电路的话,对下级电路无任何影响,…

三态门与高阻状态

三态门,是指逻辑门的输出除有高、低电平两种状态外,还有第三种状态——高阻状态的门电路。高阻态相当于隔断状态(电阻很大,相当于开路)。 三态门都有一个EN控制使能端,来控制门电路的通断。 可以具备这三种…

【微机原理与接口技术】简单易学的 简单接口芯片—— 三态门 74LS244和 锁存器 74LS273

作者:MiTu_-_ 本帖内容著作权归作者所有,转载请务必保留本文链接 接口电路的基本构成 CPU通过接口与外部设备的连接示意图如下: 负责把信息从外部设备传入 CPU 的接口(端口)叫做输入接口(端口&#xff09…

三态门——概念,作用,原理

介绍一下三态门的概念、作用、原理 目录 三态门的概念 三态门的作用 实现总线结构 实现双向数据传输 三态门的原理 三态门的概念 三态门是指逻辑门的输出有三种状态:高电平状态、低电平状态、高阻状态。 其中,高阻状态相当于隔离状态(…

数字IC设计中的三态门原理

数字电路中的三态门 可参考另外一篇博客数字电路基础知识——CMOS门电路 (与非门、或非、非门、OD门、传输门、三态门) 三态门除了高低电平,还有第三个状态——高阻态。 三态门(Three-state gate)是一种重要的总线接口电路。也常常出现在芯片…

计算机电源缓冲器,集成电路中缓冲器的作用

描述 缓冲器的概念 缓冲器在不同的领域有不同的含义。 在计算机领域,缓冲器指的是缓冲寄存器,它分输入缓冲器和输出缓冲器两种。前者的作用是将外设送来的数据暂时存放,以便处理器将它取走;后者的作用是用来暂时存放处理器送往外设…

三态门介绍

如下图,为两种形式的三态门,(a)和(b)一致;(c)和(d)一致。 对于图(a)其真值表如下: 对于图(b&#…

单片机I/O口管脚内部结构(锁存器,输出驱动器,三态缓冲器,多路开关)

学习ARM嵌入式的时候,发现自己对以前学过的数模器件的知识遗忘了不少,按照我的进度本来应该继续学习ARM微处理器控制的课程,但想着后来势必还会遇到相同的问题所以就准备中断一下,杀回来把汇编和一些电路知识再总结一下&#xff0…