求大神 求填坑告诉这些关键字的含义以及用法!

c++中explicit关键字的含义和用法
c++中explicit关键字的含义和用法
  c++中的explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?
  如果c++类的构造函数有一个参数,那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象,如下面所示:
&class MyClass{public:MyClass( int num );}....MyClass obj = 10; //ok,convert int to MyClass
  在上面的代码中编译器自动将整型转换为MyClass类对象,实际上等同于下面的操作:
  MyClass temp(10);
  MyClass obj = temp;
  上面的所有的操作即是所谓的"隐式转换".
  如果要避免这种自动转换的功能,我们该怎么做呢?嘿嘿这就是关键字explicit的作用了,将类的构造函数声明为"显示",也就是在声明构造函数的时候 前面添加上explicit即可,这样就可以防止这种自动的转换操作,如果我们修改上面的MyClass类的构造函数为显示的,那么下面的代码就不能够编 译通过了,如下所示:
  class MyClass{public:explicit MyClass( int num );}....MyClass obj = 10; //err,can't non-explict convert
  class isbn_mismatch:public std::logic_error{public:explicit isbn_missmatch(const std::string &s):std:logic_error(s){}isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):std::logic_error(s),left(lhs),right(rhs){}const std::string left,virtual ~isbn_mismatch() throw(){}};
  Sales_item& operator+(const Sales_item &lhs,const Sales_item rhs){if(!lhs.same_isbn(rhs))&& throw isbn_mismatch("isbn missmatch",lhs.book(),rhs.book());Sales_item ret(lhs);ret+}
  Sales_item item1,item2,while(cin&&item1&&item2){try{&& sun=item1+item2;}catch(const isbn_mismatch &e){&& cerr&&e.what()&&"left isbn is:"&&e.left&&"right isbn is:"&&e.right&&}}
  用于用户自定义类型的构造函数,指定它是默认的构造函数,不可用于转换构造函数。因为构造函数有三种:1拷贝构造函数2转换构造函数3一般的构造函数(我自己的术语^_^)
  另:如果一个类或结构存在多个构造函数时,explicit 修饰的那个构造函数就是默认的
  class isbn_mismatch:public std::logic_error{public:explicit isbn_missmatch(const std::string &s):std:logic_error(s){}isbn_mismatch(const std::string &s,const std::string &lhs,const std::string &rhs):std::logic_error(s),left(lhs),right(rhs){}const std::string left,virtual ~isbn_mismatch() throw(){}};
  Sales_item& operator+(const Sales_item &lhs,const Sales_item rhs){if(!lhs.same_isbn(rhs))&& throw isbn_mismatch("isbn missmatch",lhs.book(),rhs.book());Sales_item ret(lhs);ret+}
  Sales_item item1,item2,while(cin&&item1&&item2){try{&& sun=item1+item2;}catch(const isbn_mismatch &e){&& cerr&&e.what()&&"left isbn is:"&&e.left&&"right isbn is:"&&e.right&&}}
&&& 这个 《ANSI/ISO C++ Professional Programmer's Handbook 》是这样说的
  explicit ConstructorsA constructor that takes a single argument is, by default, an implicit conversion operator, which converts its argument toan object of its class (see also Chapter 3, "Operator Overloading"). Examine the following concrete example:class string{private:char *public:string();string(int size); // constructor and implicit conversion operatorstring(const char *); // constructor and implicit conversion operator~string();};Class string has three constructors: a default constructor, a constructor that takes int, and a constructor thatconstructs a string from const char *. The second constructor is used to create an empty string object with aninitial preallocated buffer at the specified size. However, in the case of class string, the automatic conversion isdubious. Converting an int into a string object doesn't make sense, although this is exactly what this constructor does.
  Consider the following:int main(){string s = "hello"; //OK, convert a C-string into a string objectint ns = 0;s = 1; // 1 oops, programmer intended to write ns = 1,}In the expression s= 1;, the programmer simply mistyped the name of the variable ns, typing s instead. Normally,the compiler detects the incompatible types and issues an error message. However, before ruling it out, the compiler firstsearches for a user-defined conversion that al indeed, it finds the constructor that takes int.Consequently, the compiler interprets the expression s= 1; as if the programmer had writtens = string(1);You might encounter a similar problem when calling a function that takes a string argument. The following examplecan either be a cryptic coding style or simply a programmer's typographical error. However, due to the implicitconversion constructor of class string, it will pass unnoticed:int f(string s);int main(){f(1); // without a an explicit constructor,//this call is expanded into: f ( string(1) );//was that intentional or merely a programmer's typo?}'In order to avoid such implicit conversions, a constructor that takes one argument needs to be declared explicit:class string{//...public:explicit string(int size); // block implicit conversionstring(const char *); //implicit conversion~string();};An explicit constructor does not behave as an implicit conversion operator, which enables the compiler to catch thetypographical error this time:int main(){string s = "hello"; //OK, convert a C-string into a string objectint ns = 0;s = 1; // this time the compiler catches the typo}Why aren't all constructors automatically declared explicit? Under some conditions, the automatic type conversion isuseful and well behaved. A good example of this is the third constructor of string:string(const char *);
  The implicit type conversion of const char * to a string object enables its users to write the following:s = "Hello";The compiler implicitly transforms this into//pseudo C++ code:s = string ("Hello"); //create a temporary and assign it to sOn the other hand, if you declare this constructor explicit, you have to use explicit type conversion:class string{//...public:explicit string(const char *);};int main(){s = string("Hello"); //explicit conversion now requiredreturn 0;}Extensive amounts of legacy C++ code rely on the implicit conversion of constructors. The C++ Standardizationcommittee was aware of that. In order to not make existing code break, the implicit conversion was retained. However, anew keyword, explicit, was introduced to the languageto enable the programmer to block the implicit conversionwhen it is undesirable. As a rule, a constructor that can be invoked with a single argument needs to be declaredexplicit. When the implicit type conversion is intentional and well behaved, the constructor can be used as animplicit conversion operator.
  网上找的讲的最好的贴:
  C++ 中 explicit 关键字的作用
  在 C++ 中, 如果一个类有只有一个参数的构造函数,C++ 允许一种特殊的声明类变量的方式。在这种情况下,可以直接将一个对应于构造函数参数类型的数据直接赋值给类变量,编译器在编译时会自动进行类型转换,将对应于构造函数参数类型的数据转换为类的对象。 如果在构造函数前加上 explicit 修饰词, 则会禁止这种自动转换,在这种情况下, 即使将对应于构造函数参数类型的数据直接赋值给类变量,编译器也会报错。
  下面以具体实例来说明。
  建立people.cpp 文件,然后输入下列内容:
  class People
  public:
  explicit People (int a)
  age=a;
  void foo ( void )
  People p1(10);& //方式一
  People* p_p2=new People(10); //方式二
  People p3=10; //方式三}
  这段 C++ 程序定义了一个类 people ,包含一个构造函数, 这个构造函数只包含一个整形参数 a ,可用于在构造类时初始化 age 变量。
  然后定义了一个函数foo,在这个函数中我们用三种方式分别创建了三个10岁的“人”。 第一种是最一般的类变量声明方式。第二种方式其实是声明了一个people类的指针变量,然后在堆中动态创建了一个people实例,并把这个实例的地址赋值给了p_p2.第三种方式就是我们所说的特殊方式,为什么说特殊呢? 我们都知道,C/C++是一种强类型语言,不同的数据类型是不能随意转换的,如果要进行类型转换,必须进行显式强制类型转换,而这里,没有进行任何显式的转换,直接将一个整型数据赋值给了类变量p3.
  因此,可以说,这里进行了一次隐式类型转换,编译器自动将对应于构造函数参数类型的数据转换为了该类的对象,因此方式三经编译器自动转换后和方式一最终的实现方式是一样的。
  不相信? 耳听为虚,眼见为实,让我们看看底层的实现方式。
  为了更容易比较方式一和方式三的实现方式,我们对上面的代码作一点修改,去除方式二:
  void foo ( void )
  People p1(10);& //方式一
  People p3=10; //方式三
  }&&& 去除方式二的原因是方式二是在堆上动态创建类实例,因此会有一些额外代码影响分析。修改完成后,用下列命令编译 people.cpp
  $ gcc -S people.cpp
  "-S"选项是GCC输出汇编代码。命令执行后,默认生成people.s。 关键部分内容如下:
  .globl _Z3foov
  .type _Z3foov, @function
  _Z3foov:
  .LFB5:
  pushl %ebp
  .LCFI2:
  movl %esp, %ebp
  .LCFI3:
  subl $24, %esp
  .LCFI4:
  movl $10, 4(%esp)
  leal -4(%ebp), %eax
  movl %eax, (%esp)
  call _ZN6PeopleC1Ei
  movl $10, 4(%esp)
  leal -8(%ebp), %eax
  movl %eax, (%esp)
  call _ZN6PeopleC1Ei
  看“.LCFI4” 行后面的东西,1-4行和5-8行几乎一模一样,1-4行即为方式一的汇编代码,5-8即为方式三的汇编代码。 细心的你可能发现2和6行有所不同,一个是 -4(%ebp) 而另一个一个是 -8(%ebp) ,这分别为类变量P1和P3的地址。
  对于不可随意进行类型转换的强类型语言C/C++来说, 这可以说是C++的一个特性。哦,今天好像不是要说C++的特性,而是要知道explicit关键字的作用?
  explicit关键字到底是什么作用呢? 它的作用就是禁止这个特性。如文章一开始而言,凡是用explicit关键字修饰的构造函数,编译时就不会进行自动转换,而会报错。
  让我们看看吧! 修改代码:
  class People
  public:
  explicit People (int a)
  age=a;
  然后再编译:
  $ gcc -S people.cpp
  编译器立马报错:
  people.cpp: In function ‘void foo()’:
  people.cpp:23: 错误:请求从 ‘int’ 转换到非标量类型 ‘People’
&&&主编推荐
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&&&湘教QS2-164&&增值电信业务经营许可证湘B2-新手问题求解:Java中this关键字的含义及用法
[问题点数:10分,结帖人abner_me]
新手问题求解:Java中this关键字的含义及用法
[问题点数:10分,结帖人abner_me]
不显示删除回复
显示所有回复
显示星级回复
显示得分回复
只显示楼主
本帖子已过去太久远了,不再提供回复功能。化学选择题,求正确答案求大神顺便标明关键字,我好理解_百度作业帮
化学选择题,求正确答案求大神顺便标明关键字,我好理解
化学选择题,求正确答案求大神顺便标明关键字,我好理解
13.A倒入水槽是绝不允许的,怕污染环境.倒回容器内也不行,因为拿出来就已经与空气接触,不干净了.拿回家那更是作死.14.C之所以用磷是因为磷燃烧后生成的是五氧化二磷,是固体,氧气消耗多少体积就会减多少.换成碳的话燃烧生成二氧化碳,是气体,体积不会减少.15.A这个是常识,背过就行了.16.C既然这个东西没有变化,那肯定是催化剂17.D水中只有一种分子,就是水分子.而分解后生成了氢分子和氧分子.
这样不会提高成绩,只是完成了“任务”。新手有些关键词不理解求大神解释_nba2kol吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0可签7级以上的吧50个
本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:516,478贴子:
新手有些关键词不理解求大神解释
经常听到有大神说运动扣 卡柱子 大招这些词但是一个都不懂。。求解
意思是说一天后不用就自...
就是g家买卖听人家说卖...
是在不理解总路程跟我想...
看了老长时间了,依然不...
(同样的照片自镇)在我...
如题,第1、3题是二重积...
【云南女导游嫌购物少威...
在这种左宽右窄情况下车...
什么网店不网店的。我不...
内&&容:使用签名档&&
保存至快速回贴

我要回帖

更多关于 求大神ps 的文章

 

随机推荐