c++11 的explicit关键字 -- 显示构建对象

概述:

在平时我们定义一个类,然后创建类对象可以有多种方式,主要分为两种:

声明一个Student类:  

class Student {
public:
     Student(int age) {
         m_age = age;
     }

private:
    int m_age;
};

  • 显示构建(explicit)
    Student s1(5);     // 像这种形式的构建对象,就是显示构建
  • 隐式构建(implicit)
    Student s1 = 5;   //  像这种形式的构建对象,就是隐式构建
     

如何区别显示构建和隐式构建?
在上述的隐式构建中,我们直接使用=将5赋值给了对象s1,这是这个表达式给我们的直观印象(也是这个原因,才提出explicit关键字)。

但是,它并不是赋值,编译器会根据赋值变量的类型(对象),去调用相应的构造函数,=后面的数字会作为参数,来实现堆对象的构建。


而显示构建是使用()运算符传入一个参数,去构建对象,很直观的可以看出其是通过调用某个函数(构造函数),去创建对象。

  • explicit关键字的作用
    explicit的意思就是显示的意思,它是用来修饰类的构造函数的,被explicit修饰的构造函数,我们在调用它去构建对象的时候,只能显示的去构建,不能隐式的去构建

  • 使用explicit的原因
    隐式构建对象Student s1 = 5;  这样的表达式直观看来就好像是直接将5赋值给s1,而其实际是去调用对应的构造函数,并不是一个赋值语句。
    所以,为了避免这种歧义,我们使用explicit关键字,来指定使用对应构造函数去构造对象的时候,只能显示的去构造,不能使用上面隐式的方式,来避免这种歧义。

 

explicit作用于普通构造函数

下面代码中,我们使用explicit关键字修饰Student类的构造函数,会发现下面隐式的去构造s1对象的时候报错了。 

 

 

explicit关键字作用于拷贝构造函数 

和上面同理,我们也可以将explicit关键字作用于拷贝构造函数上,这样其也复发使用=进行构建了。 


下面代码中会发现,我们使用explicit关键字修饰拷贝构造函数,Student s1 = Student(5); // 这样去调用靠北构造函数也就会报错。

 

 

使用explicit之后在函数传参的时候应该注意 

没加explicit关键字 

class Student {
public:
	 Student(int age) {
		m_age = age;
	 }

	 Student(const Student& stu) {
		 this->m_age = stu.m_age;
	 }

private:
	int m_age;
};

void Demo(Student s1) {
	std::cout << "Demo" << std::endl;
}

int main(void) {
	Student s1(5);
	Demo(5);
	Demo(s1);

	std::cin.get();
	return 0;
}

我们写了Demo函数,其形式参数我们传入一个Student类的对象,会发现main中我们给函数传递5,或者s1对象是允许的。
Demo(5);   // 就相当于Student s1 = 5;

Demo(s1); // 就相当于 Student s1 = s1; 

 

加上explicit关键字 

 

会发现加上explicit关键字之后,我们上面调用Demo()就出现了问题,因为上面说了,函数调用的过程其实就是隐式构建对象的过程,所以加上explicit之后就不能使用隐式构建对象了,自然就报错了。 

 

总结: 

explicit关键字就是为了解决隐式构建对象过程中带来的歧义,会容易让人理解为赋值语句,而不是调用构造函数。

给相应的构造函数加上explicit关键字之后,我们就不能在使用=去调用构造函数了(隐式)。(普通构造函数或者拷贝构造函数都是)


其实,拷贝构造函数即使使用=隐式构建,也并不会有太大歧义,当然也是根据自己的需求来定。

注意:   c++中只有explicit关键字来指定显示构建对象,是没有implicit关键字的,我们只要什么也不写就默认是隐式的了,隐式的状态下既可以隐式构建对象,也可以显示构建对象。 

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

全栈开发之路——前端篇(5)组件间通讯和接口等知识补充

全栈开发一条龙——前端篇 第一篇&#xff1a;框架确定、ide设置与项目创建 第二篇&#xff1a;介绍项目文件意义、组件结构与导入以及setup的引入。 第三篇&#xff1a;setup语法&#xff0c;设置响应式数据。 第四篇&#xff1a;数据绑定、计算属性和watch监视 辅助文档&…

WPF 图片显示某一部分区域

效果图&#xff1a; 代码&#xff1a; <Image Width"32"HorizontalAlignment"Right"Height"32"Source"../../Resources/Images/BLUEWOLF.jpg"><Image.Clip><PathGeometry><PathFigure StartPoint"32,32&quo…

重写muduo之Thread、EventLoopThread、EventLoopThreadPool

目录 1、概述 2、Thread 2.1 Thread.h 3、EventLoopThread 3.1 EventLoopThread.h 3.2 EventLoopThread.cc 4、 EventLoopThreadPool 4.1 EventLoopThreadPool.h 4.2 EventLoopThreadPool.cc 1、概述 管理事件循环线程的调度的 打包了一个EventLoop和线程&#xff0c;…

在ubuntu虚拟机中手动安装VMware Tools(VMware Workstation 17 player)

可参考官方文档&#xff1a;在 Linux 虚拟机中手动安装 VMware Tools 以下列出我在安装过程中遇见的问题&#xff1a; 1、“安装VMware Tools”选项为灰&#xff0c;无法选中 原因是VMware Tools的安装包镜像在Player的安装目录下&#xff0c;需要在虚拟机启动的时候加载这个…

【数字经济】上市公司供应链数字化数据(2000-2022)

数据来源&#xff1a; 时间跨度&#xff1a;2000-2022年 数据范围&#xff1a;各上市企业 数据指标&#xff1a; 样例数据&#xff1a; 参考文献&#xff1a;[1]刘海建,胡化广,张树山,等.供应链数字化的绿色创新效应[J].财经研究,2023,49(03):4-18. 下载链接&#xff1a;https:…

关系型数据库MySQL开发要点之多表查询2024详解

多表查询 准备测试数据 -- 部门管理 create table tb_dept(id int unsigned primary key auto_increment comment 主键ID,name varchar(10) not null unique comment 部门名称,create_time datetime not null comment 创建时间,update_time datetime not null comment 修改时…

图神经网络综述和学习路径

应用邻域 应用举例 应用层面&#xff08;节点&#xff0c;连接&#xff0c;子图&#xff0c;全图&#xff09; 概念区别 图神经网络本质上解决了表示学习的问题 可以把神经网络看作一个黑箱&#xff0c;图中的f函数 困难与挑战 现代的深度学习&#xff0c;如何把图输入到神经…

Clion STM32CubeMX 项目

系列文章目录 前言 最后修改 2024 年 4 月 16 日 操作系统&#xff1a;Windows / Linux / macOS 所需工具 STM32CubeMX、GNU ARM 工具链 项目格式&#xff1a; CMake 兼容配置&#xff1a; OpenOCD 运行与调试/嵌入式 GDB 服务器 对于以 STM32 板卡为目标的嵌入式项目&#xf…

QX-mini51单片机学习-----(3)流水灯

目录 1宏定义 2函数的定义 3延时函数 4标准库函数中的循环移位函数 5循环移位函数与左移和右移运算符的区别 6实例 7keil中DeBug的用法 1宏定义 是预处理语句不需要分号 #define uchar unsigned char//此时uchar代替unsigned char typedef是关键字 后面是接分号…

【Linux】线程的内核级理解详谈页表以及虚拟地址到物理地址之间的转化

一、线程的概念 对于进程来说&#xff0c;进程创建时间和空间成本较高&#xff0c;因为进程是承担分配系统资源的基本实体&#xff0c;所以线程的出现就成为了必然。Linux线程与进程非常相似&#xff0c;Linux设计者在设计之初觉得如果再为线程设计数据结构和调度算法就会使整个…

java--io流(一)

1. 前置知识 字符集是什么&#xff1f; 字符集&#xff08;Character Set&#xff09;是一组字符的集合&#xff0c;它定义了可以在计算机系统中使用的所有字符。字符集可以包括字母、数字、标点符号、控制字符、图形符号等。字符集使得计算机能够存储、处理和显示各种语言和…

idea 项目 修改项目文件名 教程

文章目录 目录 文章目录 修改流程 小结 概要流程技术细节小结 概要 原项目名 修改流程 关掉当前项目的idea页面 修改之后的文件名 重新打开idea。选择项目打开项目页面 技术细节 出现下面这个问题&#xff0c;可以参考作者新的一编文章idea开发工具 项目使用Spring框架开发解…

【智能楼宇秘籍】一网关多协议无缝对接BACnet+OPC+MQTT

在繁华的都市中心&#xff0c;一座崭新的大型商业综合体拔地而起&#xff0c;集购物、餐饮、娱乐、办公于一体&#xff0c;是现代城市生活的缩影。然而&#xff0c;这座综合体的幕后英雄——一套高度集成的楼宇自动化系统&#xff0c;正是依靠多功能协议网关&#xff0c;实现了…

《从零开始,搭建一个简单的UVM验证平台》实操

最近的工作中需要用UVM平台去仿真软件同事写的C程序&#xff0c;虽然只要用EDA同事已经搭好的UVM平台稍微改改就行&#xff0c;但对于我这种从未接触过UVM甚至都没用过System Verilog的纯FPGA工程师来说还是很有难度的&#xff0c;因为我对这方面一点概念都没有。 基于此&…

一文盘点 Partisia Blockchain 生态 4 月市场进展

Partisia Blockchain 是一个以高迸发、隐私、高度可互操作性、可拓展为特性的 Layer1 网络。通过将 MPC 技术方案引入到区块链系统中&#xff0c;以零知识证明&#xff08;ZK&#xff09;技术和多方计算&#xff08;MPC&#xff09;为基础&#xff0c;共同保障在不影响网络完整…

redis--安装

简介 官网&#xff1a;RedisInsight - The Best Redis GUI 各个版本官网下载地址&#xff1a;http://download.redis.io/releases/ Redis和Memcached是非关系型数据库也称为NoSQL数据库&#xff0c;MySQL、Mariadb、SQL Server、PostgreSQL Oracle 数据库属于关系型数据 应用…

17.接口自动化学习-日志

1.日志输出渠道 &#xff08;1&#xff09;文件格式 xx.log &#xff08;2&#xff09;控制台输出 2.日志级别 debug<info<warnning<error<critical 3.代码实现 from utils.handle_path import log_path import logging import datetime def logger(fileLogTr…

rocketMQ-常用知识点

1、RocketMQ有什么作用&#xff1f; 1、应用解耦 系统的耦合性越高&#xff0c;容错性就越低。以电商应用为例&#xff0c;用户创建订单后&#xff0c;如果耦合调用库存系统、物流系统、支付系统&#xff0c;任何一个子系统出了故障或者因为升级等原因暂时不可用&#xff0c;都…

多线程【阻塞队列】(生产者消费者模型代码实现)

阻塞队列 解耦合削峰填谷生产者消费者模型&#xff1a; 解耦合 削峰填谷 生产者消费者模型&#xff1a; 正常来说&#xff0c;wait通过notify唤醒&#xff0c;其他线程调用了take,在take的最后一步进行notify. package thread; class MyBlockingQueue{private String [] data…

OpenCV 入门(二)—— 车牌定位

OpenCV 入门系列&#xff1a; OpenCV 入门&#xff08;一&#xff09;—— OpenCV 基础 OpenCV 入门&#xff08;二&#xff09;—— 车牌定位 OpenCV 入门&#xff08;三&#xff09;—— 车牌筛选 OpenCV 入门&#xff08;四&#xff09;—— 车牌号识别 OpenCV 入门&#xf…