首页 > 编程语言 >C++中的explicit关键字 - 抑制隐式转换

C++中的explicit关键字 - 抑制隐式转换

时间:2022-12-26 10:12:04浏览次数:37  
标签:String int explicit C++ CExample 隐式 构造函数

在C++程序中很少有人去使用 explicit 关键字,不可否认,在平时的实践中确实很少能用的上。再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。但稍微留心一下就会发现现有的MFC库或者C++标准库中的相关类声明中explicit出现的频率是很高的。了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用。既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用。 按默认规定,只用传一个参数的构造函数也定义了一个隐式转换。举个例子: (下面这个CExample没有什么实际的意义,主要是用来说明问题)   复制代码

//Example.h 

#pragma once 

class CExample 

{ 

public: 

CExample(void); 

public: 

~CExample(void); 

­

public: 

int m_iFirst; 

int m_iSecond; 

public: 

CExample(int iFirst, int iSecond = 4); 

}; 

//Example.cpp 

#include "StdAfx.h" 

#include "Example.h" 

CExample::CExample(void) 

: m_iFirst(0) 

{ 

} 

CExample::~CExample(void) 

{ 

} 

CExample::CExample(int iFirst, int iSecond):m_iFirst(iFirst), m_iSecond(iSecond) 

{ 

} 

//TestExplicitKey.cpp 

...//其它头文件 

#include "Example.h" 

int _tmain(int argc, _TCHAR* argv[]) 

{ 

CExample objOne; //调用没有参数的构造函数 

CExample objTwo(12, 12); //调用有两个参数的构造函数 

CExample objThree(12); //同上,可以传一个参数是因为该构造函数的第二个参数有默认值 

CExample objFour = 12; //执行了隐式转换,等价于CExample temp(12);objFour(temp);注意这个地方调用了 

//编译器为我们提供的默认复制构造函数 

return 0; 

} 

如果在构造函数声明中加入关键字explicit,如下 

explicit CExample(int iFirst, int iSecond = 4); 

那么CExample objFour = 12; 这条语句将不能通过编译。在vs05下的编译错误提示如下 

error C2440: 'initializing' : cannot convert from 'int' to 'CExample' 

        Constructor for class 'CExample' is declared 'explicit' 

对于某些类型,这一情况非常理想。但在大部分情况中,隐式转换却容易导致错误(不是语法错误,编译器不会报错)。
隐式转换总是在我们没有察觉的情况下悄悄发生,除非有心所为,隐式转换常常是我们所不希望发生的。
通过将构造函数声明为explicit(显式)的方式可以抑制隐式转换。也就是说,explicit构造函数必须显式调用。 引用一下Bjarne Stroustrup的例子: class String{ explicit String(int n); String(const char *p); }; String s1 = 'a'; //错误:不能做隐式char->String转换 String s2(10); //可以:调用explicit String(int n); String s3 = String(10);//可以:调用explicit String(int n);再调用默认的复制构造函数 String s4 = "Brian"; //可以:隐式转换调用String(const char *p);再调用默认的复制构造函数 String s5("Fawlty"); //可以:正常调用String(const char *p); void f(String); ­ String g() { f(10); //错误:不能做隐式int->String转换 f("Arthur"); //可以:隐式转换,等价于f(String("Arthur")); return 10; //同上 }
复制代码 在实际代码中的东西可不像这种故意造出的例子。 发生隐式转换,除非有心利用,隐式转换常常带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的。 原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。

标签:String,int,explicit,C++,CExample,隐式,构造函数
From: https://www.cnblogs.com/kn-zheng/p/17005082.html

相关文章

  • 蓝桥-13届-C++-B组-省赛-G题-积木画
    直达链接当时第一眼看到觉得题型挺眼前一亮的,但是怎么做,没想法,也不明白考点在哪里画布高度固定是2,但是积木可以任意旋转,可以说L型只能和自己组合怎么用编程解决空间问题......
  • 精通visual c++指纹模式识别系统算法及实现
    通过学习,掌握以下几个问题:1、核心算法,并且向GVF衍生;2、核心库封装的方法2016年11月16日06:52:51昨日实现了梯度场和频率场的计算。最大的感觉就是建立基础代码库的重要性。......
  • 平台调用 (P/Invoke):托管代码(C#)调用非托管代码(C/C++)
      首先,本文基于.net6来实现C#代码来调用C/C++程序(VS2022),主要从三个角度来说明:简单的调用实现、自定义类和结构体、回调函数。  其次,C#调用C/C++一般是通过调用C/C++的......
  • C++团购订单信息管理系统
    C++团购订单信息管理系统团购订单信息管理系统功能说明:要求编写一个团购订单信息管理系统。系统包含对订单的添加、查询、修改、删除和浏览等功能。系统设有口令,只有......
  • c++const关键字
    1、用来定义常量2、定义常量指针不可通过常量指针修改其指向的内容intn,m;constint*p=&n;//编译出错,通过常量指针p修改了n的值是不允许的*p=5;n=4;/......
  • C++11:支持函数模板的默认模板参数
    在C++98/03标准中,类模板可以有默认的模板参数,如下:template<typenameT,typenameU=int,UN=0>structFoo{//...};但是却不支持函数的默认模板参数:te......
  • 浅谈 C++ 模板 & 泛化 (妈妈再也不用担心我不会用 std::sort 了)
    基础复习先上个对int类型数组的插入排序:voidinsertionSort_01(int*seq,intfirstIndex,intlastIndex){for(intj=firstIndex+1;j<=lastIndex;++j......
  • C++中头文件由来及使用细节
    在刚学习C++的时候,无法一下子习惯头文件’.h’这个东西,因为在C#中,通常函数/变量的声明和实现都是写在一起的,跨.cs文件调用其他类成员时,编译器并不会冒出’未找到该......
  • C++类模板、函数模板
    类模板的声明需要template<typename类型参数>,等于C#中的泛型类,如List<T>。template<typenameT>classComplex{public://构造函数Complex(Ta,Tb)......
  • Vscode c/c++环境
    最简单的环境,用vscode插件compilec/c++,只支持单个文件,不能调试,插件主页很短一看就懂单个文件我比较喜欢用命令行编译和运行/调试多个文件cmake/makefile mac调试-lld......