explicit constructor(显示构造函数)
按照默认规定,只有一个参数的构造函数也定义了一个隐式转换,将该构造函数对应的数据类型的数据转换为该类对象,如下所示:
- class String
- {
- String(const char* p) //用C风格的字符串p作为初始值
- //........
- }
- String s1 = "hello"; //OK,隐式转换,等价于String s1 = String('hello')
但是有的时候可能会不需要这种隐式转换,如下:
- class String
- {
- String(int n) //本意是预先分配n个字节给字符串
- String(const char* p); //用C风格的字符串p作为初始值
- //........
- }
下面的两种写法是正常的:
- String s2(10); //OK,即分配10个字节的空字符串
- String s3 = String (10); //OK,即分配10个字节的空字符串
但是以下的两种写法会使我们感到疑惑:
- String s4 = 10; //编译通过,即分配了10个字节的空字符串
- String s5 = 'a'; //编译通过,分配int('a')个字节的空字符串
s4和s5分别是把一个int型和char型,隐式转换成了分配若干个字节的空字符串,容易令人误解。
为了避免这种错误的发生,我们可以声明显示的转换,即使用explicit关键字:
- class String
- {
- <span style="color:#cc0000;">explicit</span> String(int n) //本意是预先分配n个字节给字符串
- String(const char* p); //用C风格的字符串p作为初始值
- //........
- }
加上explicit,就抑制了String(int n)的隐式转换
即下面的两种写法仍然是正确的:
- String s2(10); //OK,即分配10个字节的空字符串
- String s3 = String (10); //OK,即分配10个字节的空字符串
但是先前的两种写法就编译不能通过了,例如:
- String s4 = 10; //编译不通过,不允许隐式转换
- String s5 = 'a'; //编译不通过,不允许隐式转换
因此某些时候,explicit可以有效地防止构造函数的隐式转换带来的错误或者误解。
举例进一步阐释:
explicit只对构造函数起作用,用来抑制隐式转换,如下:
- class A
- {
- A(int a);
- };
- int Function(A a);
当调用Function(2)的时候,会隐式转换为A类型。这种情况常常不是我们所想要的结果,所以,要避免这种情形,我们就可以这样写:
- class A
- {
- explicit A(int a);
- };
- int Function(A a);
这样,当调用Function(2)的时候,编译器会给出错误的信息(除非Function有个以int为参数的重载形式),这就避免了在我们毫不知情的情况下出现的错误。
explicit constructor(显示构造函数)的更多相关文章
- 错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit constructor
错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit con ...
- C++ explicit constructor/copy constructor note
C++:explict 作用显示声明构造函数只能被显示调用从而阻止编译器的隐式转换,类似只能用()显示调用,而不能=或者隐式调用 #include <iostream> #include ...
- Implicit super constructor xx() is undefined for default constructor. Must define an explicit constructor
错误:Implicit super constructor xx() is undefined for default constructor. Must define an explicit c ...
- Eclipse错误:Implicit super constructor ClassName is undefined for default constructor. Must define an explicit constructor
public class Test01 { private String name; private int age; public Test01(String name){ this.name = ...
- C++ essentials 之 explicit constructor
这篇博客的源起是我下面的一段代码 #include <bits/stdc++.h> using namespace std; int main(){ priority_queue<l ...
- C# 转换运算符:implicit(隐式),explicit(显示)
//A类 class Cls1 { public string name; //构造函数 public Cls1(string name) { this.name = name; } //implic ...
- 构造器(Constructor)--构造函数
构造器是类型的成员之一,其他成员比如,成员字段,成员函数.狭义上,构造器指的是实例构造器(instance constructor) class Student { public int ID; pu ...
- c#自定义类型的转换方式operator,以及implicit(隐式)和explicit (显示)声明
https://docs.microsoft.com/zh-cn/dotnet/csharp/language-reference/keywords/explicit https://docs.mic ...
- Implicit super constructor Array() is undefined for default constructor. Must define an explicit constructor
因为你的父类已经创建了一个带参的构造函数并且父类中没有无参的构造函数,此时编译器不会为你调用默认的构造函数, 所以子类在继承父类的时候需要在自己的构造函数中显式的调用父类的构造函数,这样才能确保子类在 ...
随机推荐
- shader 的 nounroll
刚刚解决了一个特别坑的问题. 客户有个需求 需要shader里面 loop 的iterator数量 在运行时确定.z 这样对于里面存在 sample的loop就会被force unroll但因为co ...
- ASP.NET的一套笔试题
1. 自定义控件如何做?答:自定义控件,跟HtmlControl或WebControl相似,编译后可以添加引用到工具栏里面,直接用鼠标拖动使用.2.界面的布局?答:表格,div3.程序的执行过程 ...
- css 内联元素inline 行框全解
首先看一篇文章: CSS框模型:一切皆为框 — 从行框说起 一 行框 看图说话 上图代表了框模型中的行框.line-height 属性设置行间的距离(行高).该属性会影响行框的布局.在应用到一个块级元 ...
- Windows 8关机的三个最简单方法
Win8怎么关机?全新的Win8系统给用户一个难题,Win8如何关机?笔者整理了Win8关机的最实用的三个方法,希望能让大家了解Win8关机的具体操作,解决Win8如何关机等问题. 最常规的Win8关 ...
- iOS工程预编译文件的创建
在搜索 添加工程名/自己的pch文件名记住加后缀
- UVA 562 Dividing coins
题目描述:给出一些不同面值的硬币,每个硬币只有一个.将这些硬币分成两堆,并且两堆硬币的面值和尽可能接近. 分析:将所有能够取到的面值数标记出来,然后选择最接近sum/2的两个面值 状态表示:d[j]表 ...
- BackgroundWorker组件
BackgroundWorker组件封装了后台线程的操作,并且直接利用线程池,无需自己管理线程池等复杂问题. 它主要适用于 比如界面后台加载数据,进度显示,上传下载文件,日月结等 这些都是繁重的劳动, ...
- 很不错的文章---【问底】徐汉彬:亿级Web系统搭建——单机到分布式集群
[导读]徐汉彬曾在阿里巴巴和腾讯从事4年多的技术研发工作,负责过日请求量过亿的Web系统升级与重构,目前在小满科技创业,从事SaaS服务技术建设. 大规模流量的网站架构,从来都是慢慢“成长”而来.而这 ...
- Combination Sum III
https://leetcode.com/problems/combination-sum-iii/ Find all possible combinations of k numbers that ...
- C 和C++ 名称修饰规则
C名称修饰规则 1.对于使用__cdecl调用约定的函数,在函数名称前加一下划线,不考虑参数和返回值. 2.对于使用__fastcall调用约定的函数,在函数名称前后各加一@符号,后跟参数的长度,不考 ...