C++ explicit关键字

C++中的explicit关键字

             <div id="article_content" class="article_content clearfix">
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-211130ba7a.css">
                        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-211130ba7a.css">
            <div class="htmledit_views" id="content_views">
        在C++程序中很少有人去使用explicit关键字,不可否认,在平时的实践中确实很少能用的上。再说C++的功能强大,往往一个问题可以利用好几种C++特性去解决。但稍微留心一下就会发现现有的MFC库或者C++标准库中的相关类声明中explicit出现的频率是很高的。了解explicit关键字的功能及其使用对于我们阅读使用库是很有帮助的,而且在编写自己的代码时也可以尝试使用。既然C++语言提供这种特性,我想在有些时候这种特性将会非常有用。
按默认规定,只用传一个参数的构造函数也定义了一个隐式转换。举个例子:
//Example.h

  
  
  1. #pragma once
  2. class CExample
  3. {
  4. public:
  5. CExample( void);
  6. public:
  7. ~CExample( void);
  8. public:
  9. int m_iFirst;
  10. int m_iSecond;
  11. public:
  12. CExample( int iFirst, int iSecond = 4);
  13. };
//Example.cpp

  
  
  1. #include "StdAfx.h"
  2. #include "Example.h"
  3. CExample::CExample( void)
  4. : m_iFirst( 0)
  5. {
  6. }
  7. CExample::~CExample( void)
  8. {
  9. }
  10. CExample::CExample( int iFirst, int iSecond):m_iFirst(iFirst), m_iSecond(iSecond)
  11. {
  12. }
//TestExplicitKey.cpp

  
  
  1. //其它头文件
  2. #include "Example.h"
  3. int _tmain( int argc, _TCHAR* argv[])
  4. {
  5. CExample objOne; //调用没有参数的构造函数
  6. CExample objTwo(12, 12); //调用有两个参数的构造函数
  7. CExample objThree(12); //同上,可以传一个参数是因为该构造函数的第二个参数有默认值
  8. CExample objFour = 12; //执行了隐式转换,等价于CExample temp(12);objFour(temp);注意这个地方调用了
  9. //编译器为我们提供的默认复制构造函数
  10. return 0;
  11. }
如果在构造函数声明中加入关键字explicit,如下
explicit CExample(int iFirst, int iSecond = 4);
那么CExample objFour = 12; 这条语句将不能通过编译。在vs05下的编译错误提示如下
error C2440: 'initializing' : cannot convert from 'int' to 'CExample'
 
对于某些类型,这一情况非常理想。但在大部分情况中,隐式转换却容易导致错误(不是语法错误,编译器不会报错)。隐式转换总是在我们没有察觉的情况下悄悄发生,除非有心所为,隐式转换常常是我们所不希望发生的。通过将构造函数声明为explicit(显式)的方式可以抑制隐式转换。也就是说,explicit构造函数必须显式调用。
引用一下Bjarne Stroustrup的例子:

  
  
  1. class String
  2. {
  3. explicit String(int n);
  4. String( const char *p);
  5. };
  6. String s1 = 'a'; //错误:不能做隐式char->String转换
  7. String s2(10); //可以:调用explicit String(int n);
  8. String s3 = String( 10); //可以:调用explicit String(int n);再调用默认的复制构造函数
  9. String s4 = "Brian"; //可以:隐式转换调用String(const char *p);再调用默认的复制构造函数
  10. String s5("Fawlty"); //可以:正常调用String(const char *p);
  11. void f(String);
  12. String g()
  13. {
  14. f( 10); //错误:不能做隐式int->String转换
  15. f( "Arthur"); //可以:隐式转换,等价于f(String("Arthur"));
  16. return 10; //同上
  17. }
在实际代码中的东西可不像这种故意造出的例子。
发生隐式转换,除非有心利用,隐式转换常常带来程序逻辑的错误,而且这种错误一旦发生是很难察觉的。
原则上应该在所有的构造函数前加explicit关键字,当你有心利用隐式转换的时候再去解除explicit,这样可以大大减少错误的发生。

C++中的explicit关键字只能用于修饰只有一个参数的类构造函数, 它的作用是表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式)。

但是, 也有一个例外, 就是当除了第一个参数以外的其他参数都有默认值的时候, explicit关键字依然有效, 此时, 当调用构造函数时只传入一个参数, 等效于只有一个参数的类构造函数。


原文链接:http://blog.csdn.net/chollima/article/details/3486230



        <div class="person-messagebox">
            <div class="left-message"><a href="https://blog.csdn.net/caoshangpa">
                <img src="https://profile.csdnimg.cn/8/E/A/3_caoshangpa" class="avatar_pic" username="caoshangpa">
            </a></div>
            <div class="middle-message">
                                    <div class="title"><span class="tit "><a href="https://blog.csdn.net/caoshangpa" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;,&quot;ab&quot;:&quot;new&quot;}" target="_blank">灿哥哥</a></span>
                    <!-- 等级,level -->
                                            <img class="identity-icon" src="https://csdnimg.cn/identity/blog7.png">                                            </div>
                <div class="text"><span>原创文章 253</span><span>获赞 2479</span><span>访问量 236万+</span></div>
            </div>
                            <div class="right-message">
                                        <a class="btn btn-sm attented bt-button personal-watch" data-report-click="{&quot;mod&quot;:&quot;popu_379&quot;,&quot;ab&quot;:&quot;new&quot;}">已关注</a>
                                                            <a href="https://bbs.csdn.net/topics/395526274" target="_blank" class="btn btn-sm bt-button personal-messageboard">他的留言板
                    </a>
                                </div>
                        </div>
                    
    </div>
</article>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值