参考:http://www.weixueyuan.net/view/6343.html

总结:

  带参数的构造函数中有两种比较常见的构造函数:拷贝构造函数和转型构造函数。

  转型构造函数只有一个参数,如果该参数是int型,则我们是将int型对象转换为类对象。

  直接强制关闭掉这种隐式类型转换,在C++中,通过关键字explicit可以实现该功能。

  在C++中, 如果的构造函数只有一个参数时, 那么在编译的时候就会有一个缺省的转换操作:将该构造函数对应数据类型的数据转换为该类对象。

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

   explicit关键字只对有一个参数的类构造函数有效, 如果类构造函数参数大于或等于两个时, 是不会产生隐式转换的, 所以explicit关键字也就无效了.

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

在前面,我们已经将构造函数划分为两类:默认构造函数(不带参数的构造函数)和带参构造函数。其中带参数的构造函数中有两种比较常见的构造函数:拷贝构造函数和转型构造函数。我们先来了解一下转型构造函数。

转型构造函数用于类型间的转换,将其它数据类型转变为类的对象类型。转型构造函数只有一个参数,如果该参数是int型,则我们是将int型对象转换为类对象,如果该参数类型为char *类型,我们则是将字符串常量转换为类对象。

例1:

  1. class Age
  2. {
  3. public:
  4. Age(int a){age = a;}
  5. private :
  6. int age;
  7. }

在本例中Age(int a)即为一个转型构造函数,该构造函数仅有一个参数,该构造函数是将int型转换为类对象类型的。

例2:

  1. class student
  2. {
  3. public:
  4. student(){}
  5. student(char * n){name = n;}
  6. private :
  7. char * name;
  8. }

在本例中,student类中有两个构造函数,一个是默认构造函数,另一个是转型构造函数,该构造函数将字符串常量转换为类对象类型。

假设我们在程序设计过程中有一个以类对象作为函数参数的函数,函数声明如下:

  1. void fun(student s); //函数声明

如果我们设计了如下程序以调用该函数:

  1. char * name = “Harry Potter”;
  2. fun(name);

在例2中我们恰好在student类中定义了这样一个转型构造函数student(char * n);,该函数可以将字符串常量转换为student类的对象。在我们运行fun(name);语句时,编译器会自动调用转型构造函数将name转换为student类的对象,然后调用void fun(student s);函数。这一系列的过程都是编译器自动完成的,我们称此时的student类的转型构造函数student(char * n);支持隐式类型转换。之所以说是隐式的,是因为这个转型过程完全由编译器完成,无需程序设计人员显示转换类型。

隐式类型转换给程序设计人员带来了一定的便利,但是隐式类型转换可能会给我们设计的程序带来一些难以觉察的细微错误。有时候我们为了避免这种错误,我们希望直接强制关闭掉这种隐式类型转换,在C++中,通过关键字explicit可以实现该功能。

例3:

  1. class student
  2. {
  3. public:
  4. student(){}
  5. explicit student(char * n){name = n;}
  6. private :
  7. char * name;
  8. }

如例3所示,我们在转型构造函数前加上了explicit关键字,如此一来,我们再想通过以下语句:

  1. char * name = “Harry Potter”;
  2. fun(name);

调用void fun(student s);函数则是无法通过编译的,因为fun函数的参数是student类的对象而非字符串常量,并且student类的转型构造函数被标记为explicit,因此无法隐式地将字符串常量转换为student 类对象。使用explicit关键字的好处就在于将难以察觉的后期运行时可能会出现的错误提前到了编译期,如此一来改正错误就比较容易了。

2.11 C++转型构造函数的更多相关文章

  1. C++11 构造函数的改动

    一.继承构造函数 继承构造函数的引入原因:如果基类的构造函数很多,那么子类的构造函数想要实现同样多的构造接口,必须一一调用基类的构造函数,有点麻烦. 于是乎:C++11引入继承构造函数,子类可以通过使 ...

  2. C++11 常用语法

    1 新类型 C++ 11新增了long long和unsigned long long,以支持64bit宽度: 新增char16_t和char32_t以支持16位和32位字符表示: 增加了“原始”字符 ...

  3. c++11新特性(了解)

    从C++出来到现在已经13年了. Bjarne Stroustrup(C++的创造者)最近评价C++:”感觉像个新的语言“. 事实上,C++11核心已经发生了很重大的变化: . 支持Lambda表达式 ...

  4. Java编程思想(11~17)

    [注:此博客旨在从<Java编程思想>这本书的目录结构上来检验自己的Java基础知识,只为笔记之用] 第十一章 持有对象 11.1 泛型和类型安全的容器>eg: List<St ...

  5. C++11笔记

    __func__宏 __func__返回当前的函数名,也可以返回class和struct名. /*返回函数名hello*/ const char* hello() { return __func__; ...

  6. JavaScript 类、构造函数、原型

    类.构造函数.原型  :本质均为函数 利用的原理是:词法作用域,调用对象及作用域链  闭包  属性查找方式    设计和new运算符一起使用的函数叫做构造函数. 构造函数的工作:初始化一个新创建的对象 ...

  7. Spark学习笔记11面向对象编程

    面向对象编程   11.1 object类 11.1.1定义一个简单的类   11.1.2 field的getter与setter 定义类包含,定义类的field及方法.其格式如下 class Cla ...

  8. 5.9 C++重载转型操作符

    参考:http://www.weixueyuan.net/view/6387.html 注意: 转型构造函数可以将其它类型的参数转换为类类型,如果我们要进行相反的转换过程,将类类型转换为其它数据类型, ...

  9. Javascript中构造函数的返回值问题和new对象的过程

    首先明确一点:javascript中构造函数是不需要有返回值的,这一点跟java很类似.可以认为构造函数和普通函数的最大差别就是:构造函数中没有return语句,普通函数可以有return语句:构造函 ...

随机推荐

  1. (转)SPI时钟极性、时钟相位

    SPI协议是一个 4 线.全双工的串口协议.根据串口时钟SCLK的相位SCPH和极性SCPOL的不同,有 4 种组合. CPOL CPHA MODE0 0 0 MODE1 0 1 MODE2 1 0 ...

  2. 终于把joomla 的 protostar 模版的菜单,从垂直改到水平了

    protostar-applying-menu-class-suffixes-horizontal-vs-vertical-menus.html joomla 3.7.5 附带的这个template ...

  3. tstringlist详细用法

    TStringList 类是在Delphi使用最厂的一个对像,我们这里一起来看看 TStringList 的详细用法. 先把要讨论的几个属性列出来:1.CommaText2.Delimiter &am ...

  4. blast | diamond 输出结果选择和解析 | 比对

    之前的文章:构建NCBI本地BLAST数据库 (NR NT等) | blastx/diamond使用方法 | blast构建索引 | makeblastdb 本地运行blast时,需要指定out fo ...

  5. 20165327 2017-2018-2《Java程序设计》课程总结

    20165327 2017-2018-2<Java程序设计>课程总结 预备作业一:我期望的师生关系 预备作业二:学习基础和C语言基础调查 预备作业三:预备作业3 Linux安装及学习 第一 ...

  6. C# 网页图片采集

    http://blog.csdn.net/a237428367/article/details/5987832 using System; using System.Collections.Gener ...

  7. BGP - 4,BGP的三张表

    1,BGP的三张表      邻居表(adjancy table)      BGP表(forwarding database):BGP默认不做负载均衡,会选出一条最优的,放入路由表      路由表 ...

  8. 【源码分析】Mybatis使用中,同一个事物里,select查询不出之前insert的数据

    一.问题场景模拟问题:第二次查询和第一次查询结果一模一样,没有查询出我新插入的数据 猜测:第二次查询走了Mybatis缓存 疑问:那为什么会走缓存呢? 1.service方法 @Override @T ...

  9. (GoRails)链接link_to到当前页current Page 并使用参数 (类ActionController::Parameters)

    https://gorails.com/episodes/rails-link-to-current-page-with-params?autoplay=1 如何链接到当前页并增加,移除,或者修改UR ...

  10. caffe-ssd

    1.安装依赖 1 sudo apt-get install libprotobuf-dev libleveldb-dev libsnappy-dev libopencv-dev libhdf5-ser ...