C explicit 关键字详解

explicit关键字的作用

explicit关键字在写程序时使用的次数较少,但是仔细观察会发现,在C 标准库中的相关类声明中explicit出现的频率是很高的,那么explicit关键字到底有什么作用呢?接下来我就为大家一一解答。


explicit为清晰的;明确的之意.顾名思义,关键字explicit可以阻止隐式转换的发生。

例如: C 中只带有一个参数的构造函数,或者或者除了第一个参数外其余参数都有缺省值的多参构造函数,承担了两个角色:

1.用于构建单参数的类对象。

2.隐含的类型转换操作符。

例如:一个类A的构造函数A(int i)就是,既可以用来作为构造器,又可以实现隐式转换A a=1;因为1可以通过构造函数A(int i)转换为一个类A的对象。(隐含的类型转换操作符)

但有时我们并不想让他进行隐式类型转换,这时C 的explicit关键字就起到作用了。

注意:当类的声明和定义分别在两个文件中时,explicit只能写在在声明中,不能写在定义中。


下面我将为大家介绍三种使用explicit关键字的情况:

类型转换函数

#includeusing namespace std;class Fraction{public:  Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){}  operator double() const{    return (double)m_numerator/m_denominator;  }private:  int m_numerator;  int m_denominator;}
int main(void){  Fraction fraction(3, 5);  double d = 3.5   f;  cout << d << endl;  return 0;}

我们设计了一个Fraction类(分数类), 在主函数中定义了一个分数对象f,然后将3.5 f赋值给double类型变量d, 但是我们发现f并不是一个double类型的变量,因此编译器会从Fraction类中寻找operator double()函数,隐式调用该函数将Fraction类型转换成一个double类型. operator double()就是我们所说的类型转换函数(type conversion function)。

类型转换函数的一般形式

operator 数据类型 const()
{//函数实现}

1.转换函数必须是类的成员函数

2.转换函数不能声明返回类型

3.形参列表必须为空

4.类型转换函数通常应该是const

当我们想要在明确声明类型转换的时候,才使用类型转化函数时,这时我们就需要使用到explicit关键字了.使用方法如下:

#includeusing namespace std;class Fraction{public:  Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){}  explicit operator double() const{    return (double)m_numerator/m_denominator;  }private:  int m_numerator;  int m_denominator;}
int main(void){  Fraction fraction(3, 5);  double d = 3.5   static_cast<double>(f);  cout << d << endl;  return 0;}

注意,这时当我们想调用类型转换函数的时候,需要写成static_cast(f);

注意static_cast 是C 11 引入的类型转换运算符。

单操作数构造函数

还是采用上面的Fraction类,这次我们重载(overload) “ ” 号运算符,使得仍然可以达到相同的效果。

#include
using namespace std
class Fraction
{ 
public:  Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){}   double operator (const Fraction& a)   {    return (a.m_numerator   this->m_numerator)/(a.denominator   this->m_denominator);   } 
private:int m_numerator;
int m_denominator;} int main(void){  Fraction fraction(3, 5);  double d = f   3;  cout << d << endl;  return 0;
}

在double d = f 3 这句话中构造函数就是前面所提到的第二种角色隐含的类型转换操作符。因为执行到这句话首先会调用 的重载函数,该函数的调用对象默认为左操作数,右操作数为Fraction类型,因此会调用构造函数将3转换成Fraction类型,然后将得到的返回值double类型赋值给变量d。


同理如果不想让构造函数进行隐式类型转换,可以在构造函数前面加上explicit关键字,防止进行隐式转换.使用方法如下:

#include
using namespace std
class Fraction
{ 
public:explicit Fraction(int numerator, int denominator = 1): m_numerator(numerator), m_denominator(denominator){}   double operator (const Fraction& a)   {     return (a.m_numerator   this->m_numerator)/(a.denominator   this->m_denominator);  }private:  int m_numerator; int m_denominator; } int main(void){  Fraction fraction(3, 5);  double d = f   3;  cout << d << endl;  return 0;}

你可能会注意到,加上explicit 关键字之后,这个代码将不能正确执行。

来源:code_campaignblog.csdn.net/l2563898960/article/details/97769569

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/338965.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python决策树算法_决策树算法及python实现

决策树算法是机器学习中的经典算法 1.决策树(decision tree) 决策树是一种树形结构&#xff0c;其中每个内部节点表示一个属性上的测试&#xff0c;每个分支代表一个测试输出&#xff0c;每个叶节点代表一种类别。 假设小明去看电影&#xff0c;影响看电影的外部因素有 时间 电…

长见识:你真的知道C语言里extern quot;Cquot; 的作用吗?

经常在C语言的头文件中看到下面的代码&#xff1a;#ifdef __cplusplus extern "C" { #endif// all of your legacy C code here#ifdef __cplusplus } #endif这通常用于C 和C混合编程的时候&#xff0c;为了防止C 的编译器在编译C文件的时候出现错误&#xff1b;众所周…

python自动批量发邮件脚本_Python实现自动发送邮件功能

简单邮件传输协议(SMTP)是一种协议&#xff0c;用于在邮件服务器之间发送电子邮件和路由电子邮件。Python提供smtplib模块&#xff0c;该模块定义了一个SMTP客户端会话对象&#xff0c;可用于使用SMTP或ESMTP侦听器守护程序向任何互联网机器发送邮件。 SMTP通讯的基本流程可以概…

C语言中#if,#if defined ,#ifdef,extern的用法描述

1、#if 和#ifdef当asd_eee表达式存在而且&#xff0c;值为ture的时候接续向下执行例如#define TARGET_LITTLE_ENDINA 1 #define TARGET_BIG_ENDINA 0 #ifdef TARGET_LITTLE_ENDINA call little endina function #else call big endina function #endif上面的今天写的代码&…

delphi报列表索引越界怎么处理_图解Elasticsearch索引机制,此篇带你领悟新世界...

前言随着Elastic的上市&#xff0c;ELK不仅在互联网大公司得到长足的发展&#xff0c;而且在各个中小公司都得到非常广泛的应用&#xff0c;甚至连"婚庆网站"都开始使用Elasticsearch了。随之而来的是 Elasticsearch 相关部署、框架、性能优化的文章早已铺天盖地。因…

为什么C语言函数不能返回数组,却可以返回结构体

C语言函数为什么不能返回数组&#xff1f;在C语言程序开发中&#xff0c;我们不可以编写下面这样的代码&#xff1a;char f(void[8]{ char ret;// ...fill... return ret; }int main(int argc, char ** argv) {char obj_a[10];obj_a f(); }不可以编写这样的代码这其实就是不能…

C语言printf()函数具体解释和安全隐患

程序员都知道&#xff0c;也都会使用printf函数&#xff0c;但你知道它也有“安全隐患”吗&#xff1f;下面就来举例我说说&#xff1a;嵌入式专栏1问题描述打印输出的数据并不是理论值&#xff0c;如下图&#xff08;右边&#xff09;&#xff1a;嵌入式专栏2进一步描述问题请…

java map 如何根据key获得对象_ThreadLocal:Java中的影分身

关于ThreadLocal&#xff0c;你有哪些疑问&#xff1f;ThreadLocal是用来解决什么问题的&#xff1f;如何使用ThreadLocal&#xff1f;ThreadLocal的实现原理是什么&#xff1f;可否举几个实际项目中使用ThreadLocal的案例&#xff1f;基础知识ThreadLocal是线程局部变量&#…

【C语言】你可能对 sizeof() 有点误解。。。

各位&#xff0c;今天还是按照惯例给大家分享一个C语言容易出现的小错误&#xff0c;这也是跟sizeof有关的&#xff0c;问题虽小&#xff0c;却可管中窥豹&#xff0c;话不多说&#xff0c;代码先行&#xff1a;#include int main() { int i; i 8; printf("%d\…

nginx tcp转发_Nginx学习(九):负载均衡服务

介绍对于请求而言&#xff0c;负载均衡能很好的均摊请求&#xff0c;提高服务端吞吐率和整体性能&#xff0c;多个服务节点部署的方式&#xff0c;也提高了容灾和服务高可用。一、负载均衡分类负载均衡分为&#xff1a;GSLB和SLB。1. GDLB全局负载均衡&#xff0c;往往按照国家…

控制台发送get命令_.NET Core使用命令行参数库构建控制台应用程序

前言在我们开发中可能需要设计一次性应用程序&#xff0c;这些实用程序可以利用接近原始源代码的优势&#xff0c;但可以在与主Web应用程序完全独立的安全性上下文中启动。具体在 [管理过程](https://12factor.net/admin-processes)中也已经列出了原因。创建控制台应用打开命令…

C语言函数为什么不能返回数组?

C语言函数为什么不能返回数组&#xff1f;在C语言程序开发中&#xff0c;我们不可以编写下面这样的代码&#xff1a;char f(void)[8] {char ret; // ...fill... return ret; }int main(int argc, char ** argv) {char obj_a[10]; obj_a f(); }不可以编写这样的代码这其实就是不…

mockito_书评:Mockito Essentials

mockitoSujoy Acharya的Mockito Essentials副标题&#xff08; Packt出版 &#xff0c;2014年10月&#xff09;是&#xff1a;“实用指南&#xff0c;可帮助您使用Mockito进行单元测试并开始运行。” Mockito Essentials中的前言和七章涵盖大约190个实质性页面。 前言 在序言中…

C语言中quot;##quot;的独特用法

市面上有很多比较火的编程语言&#xff0c;比如Python、 JAVA、 Go等&#xff0c;你可能觉得C语言很古老、很落后。如果你有这种想法&#xff0c;那可能你只是一个初学的菜鸟。可能绝大部分 C 程序员都不知道"##"隐藏用法&#xff0c;下面就来给大家讲讲。一、##的“…

html a标签去掉下划线_如何用HTML基本元素制作表格

第2天【HTML基本元素】主要内容标题标签段落标签强制换行水平线图片超链接文本格式化标签列表表格学习目标一、标题标题&#xff08;Heading&#xff09;是通过 <h1> - <h6> 标签进行定义的。<h1> 定义最大的标题。 <h6> 定义最小的标题。标题很重要请…

C语言中几个容易踩的“坑”!

今天给大家分享几个C语言中的坑。一、带参数的宏展开顺序#include #define f(a,b) a##b #define g(a) #a #define h(a) g(a)int main(void) {printf("%s\n",h(f(1,2)));printf("%s\n",g(f(1,2)));return 0; }运行结果:12f(1,2)浅析&#xff1a;本题中的#运…

dockerfile cd目录_使用Werf和现有的Dockerfiles改善你的CI/CD体验

迟到总比不到好。该故事讲关于我们因不支持使用常规的Dockerfile来构建镜像导致我们差点犯了一个重大错误。Werf[1]是一个GitOps工具&#xff0c;可以很好地集成到任何CI/CD系统中&#xff0c;并提供完整的应用程序生命周期管理&#xff0c;允许你&#xff1a;构建和推送镜像部…

alxc tool 报错数组超出了界限_代码审计之报错信息泄露与字符串截断

机器在语言编码转换的时候&#xff0c;经常会出现各种各样的异常&#xff0c;这些神奇的字符串就有可能组合成一堆乱码出来&#xff0c;也有可能直接把程序搞崩溃掉&#xff0c;不过总有那么一些字符&#xff0c;可以帮助我们在利用漏洞的时候变得更简单一些&#xff0c;下面我…

C语言,去你的策略模式!

前言 这里先插一点题外话&#xff0c;在C语言中&#xff0c;实现封装、继承、隐藏、多态等等特性&#xff0c;是完全没有问题的。但是在使用过程中&#xff0c;必定是不如自带这些特性的语言方便好用的&#xff0c;比如C \java等。一旦要通过C语言来实现各种设计模式&#xff0…

eager_EAGER的获取是代码的味道

eager介绍 Hibernate获取策略确实可以使几乎没有爬网的应用程序和响应Swift的应用程序有所不同。 在这篇文章中&#xff0c;我将解释为什么您应该选择基于查询的获取而不是全局获取计划。 取得101 Hibernate定义了四种关联检索策略 &#xff1a; 提取策略 描述 加入 原始S…