参考: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. CRC分段校验

    crc16 modbus分段校验码: const uint8_t ModbusCRCHighTab[] = { 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x ...

  2. HTML第三章总结

    在这一章节中,主要讲了 HTML 中众多的 element,element 就像在建筑房屋时候的材料,它可以分为两种: Block Element Inline ElementBlock Elemen ...

  3. 雷林鹏分享:jQuery EasyUI 表单 - 创建树形下拉框

    jQuery EasyUI 表单 - 创建树形下拉框 树形下拉框(ComboTree)是一个带有下列树形结构(Tree)的下拉框(ComboBox).它可以作为一个表单字段进行使用,可以提交给远程服务 ...

  4. 20165327 学习基础和C语言基础调查

    学习基础和C语言基础调查 一.关于技能 1. 你有什么技能比大多人(超过90%以上)更好? 根据数据来看,应该是短跑(几次测速50米平均时间6.5s),上学期的体测中短跑这项成绩在班上排前面,我们这个 ...

  5. 【消息队列】kafka是如何保证消息不被重复消费的

    一.kafka自带的消费机制 kafka有个offset的概念,当每个消息被写进去后,都有一个offset,代表他的序号,然后consumer消费该数据之后,隔一段时间,会把自己消费过的消息的offs ...

  6. Spring Cloud之注册中心搭建

    一.注册中心服务端搭建 1)引入相关Maven坐标 <dependency> <groupId>org.springframework.cloud</groupId> ...

  7. linux进程管理之进程查看

    查看进程 process ====================================================================================了解如 ...

  8. Confluence 6 管理和恢复空间管理权限

    管理和恢复空间管理权限 可能有些空间的空间管理权限被系统的超级管理删除掉了.这样的空间是没有任何空间管理员的,用户和用户组都不能对空间进行管理.只有 Confluence 管理员权限的用户可以删除一个 ...

  9. hbase知识

    HBASE是一个高可靠性.高性能.面向列.可伸缩的分布式存储系统 HBASE的目标是存储并处理大型的数据,更具体来说是仅需使用普通的硬件配置,就能够处理由成千上万的行和列所组成的大型数据. HBASE ...

  10. 2017-4-20/Redis的数据结构及应用场景

    1. 谈谈你对redis的理解,它的应用场景. Redis是一个key-value存储系统,它支持存储的value类型包括string字符串.list链表.set集合.sorted Set有序集合和h ...