现在正式对C++中对象建立和初始化做一个总结。

  (1)复制初始化的基本原理

  我们知道,对象在内存中的直接表象是在内存中占有一个一定大小的空间。分配空间是建立对象的第一步。但是刚刚分配的空间就像一个没有开垦的荒田,或者是前面对象占有之后留下来的残余,从理论上讲,由于不管是什么大家都是0101,所以就算没有初始化也是有值的,只是这个值你是不能正确使用的。所以建立对象的关键在于如何对该对象所占有的空间进行正确的初始化。

  初始化虽然与赋值的结果很像,但是其所面临的状态和发生的时间是不同的。从他们的功能来讲,初始化与给某个变量赋值的唯一特点就是他是第一次初始化。当然当你认识到这点的时候,他们的区别也就是无所谓了。关键在于,初始化,是一个必须的赋值过程,因为如果你不做这方面的动作,你的对像是一个没有用的(或者不能正常使用的)

  直接初始化,就是使用构造函数,定义在申请了对象空间之后如何对各个子空间进行初始赋值,称他们为直接初始化是很贴切的,应为他就是最为普通的初始化,是构建一个完整对象的一个过程——先将空间申请好,然后给各个子空间(数据属性)进行相应的赋值。

  复制初始化,特点特别之处在于“复制”二字,核心意义就是,我通过对一个已有对象的完全复制,来构建对象。它的过程可以理解成这样——先申请空间,然后将被复制的对象(空间一样大)的所有内容全部复制过去,就形成了这个对象。所以,要明确,两种初始化的方式,都是一构造函数的形式存在的。区别在于他们的参数方面,复制初始化,表达的就是对一个已有同类型的对象进行复制,那么这种构造函数就应该使用某个对象来进行复制,同时因为,C++参数的传递默认都是值传递,要声明使用引用的方式(要不然就又复制了一次了);并且是const类型的。

  也就是说任何复制初始化的表面特征就是使用“=”号来表达,左边是对该对象的空间的申明,右边是另外一个同类型的对象,注意,一定是同类型的对象(即使不是,也会使用类型转换构造函数来进行构造(前面说过)!形如:

  classname objectname=objectname2;    复制初始化。
  classname objectname(,,,,,);    直接初始化,有参数。
  classname objectname;     直接初始化,没有参数。
  classname *objectpointorname=new classname(,,);   这里的操作有两个过程,先使用对象构造函数通过直接初始化构造出一个对象,然后将指针放回,不管有没有参数。
  classname objectname=other_objectname3;  这里表达的是,这个othe_objectname3,不是classname这个类型。这个个就要知道,右边的会通过调用直接初始化构造函数,构造出对应的对象,然后调用复制初始化构造函数。

  所以:构造函数应该分为1)直接初始化构造函数,和2)复制初始化构造函数。还是要说,复制初始化构造函数看起来像赋值,但是,其实只是像而已,它其实是借用了这种表象,来触发调用了那个使用同类型对象引用作为参数的复制构造函数。

  string null_book="9-999-9999-9";    先调用了隐式转换的直接初始化构造函数,然后调用了复制初始化构造函数。
  string dots(10, '.');直接调用直接初始化构造函数。
  string empty_copy=string(); 先调用显示直接初始化构造函数,然后调用复制初始化构造函数。
  string empty_direct;  直接调用没有参数的(默认)构造函数
  ifstream file1("filename");   直接初始化
  ifstream file2="filename";   虽然语法没有错,但是,由于文件对象不能复制,所以不能使用复制初始化,这种做法在文件领域中通常是错误的。
  Sales_item item=string("9-999-99999-9");  这个语法对与错,关键是看Saltes_item有没有隐式(没有使用explicity标志)转换以string类型为参数的构造函数。

  (2)构造函数(用于直接或复制初始化 )的使用模式。

  事实上,我们说这些东西特殊,关键是他们时候的时候特殊,两种构造函数(对应两种初始化方式)都有显示和隐式的构造方法。

  对于直接初始化,我们知道显示的方法,就是使用类名加上参数(其实就是在调用构造函数),隐式的方法,就是在一个需要该类对象的地方出现了其他的数据类型,于是系统会自动调用对应函数(这个应该在编译的时候应该调用了)因为这个时候可以检测出错误来。

  对于复制初始化,最显示的调用手段就是使用“=”符号(这个时候应该成为复制初始化符号)。那么还有许多地方是隐式的调用。如参数传递时,函数返回时,初始化容器时!

  1)对于参数传递:我们知道除非是引用参数,否则就是一个使用上层对象复制初始化函数参数的过程。

  2)对于函数返回值:我们知道除非是引用返回,否则在return的那个语句就是使用函数内的对象,复制初始化一个上层对象(通常是临时的,然后马上有被用于)

C++直接初始化和复制初始化2的更多相关文章

  1. C++的一大误区——深入解释直接初始化与复制初始化的区别

      转自:http://blog.csdn.net/ljianhui/article/details/9245661 不久前,在博客上发表了一篇文章——提高程序运行效率的10个简单方法,对于其中最后一 ...

  2. C++直接初始化和复制初始化1

    这篇文章主要介绍了C++直接初始化与复制初始化的区别深入解析,是很多C++初学者需要深入了解的重要概念,需要的朋友可以参考下   C++中直接初始化与复制初始化是很多初学者容易混淆的概念,本文就以实例 ...

  3. c++的直接初始化与复制初始化 未完成!!!!!!!!!!!!

    直接初始化:是直接调用类的构造函数进行初始化.如下: string a;//调用默认构造函数 string a("hello");//调用参数为 const char* 类型的构造 ...

  4. C++复制初始化的限制

    相比于直接初始化,复制初始化有更加严格的限制. 1:在复制初始化时,不能使用声明为explicit的构造函数进行的隐式转换.而直接初始化则是允许的: struct Exp { explicit Exp ...

  5. 【原创】c++拷贝初始化和直接初始化的底层区别

    说明:如果看不懂的童鞋,可以直接跳到最后看总结,再回头看上文内容,如有不对,请指出~ 环境:visual studio 2013(编译器优化关闭) 源代码 下面的源代码修改自http://blog.c ...

  6. Spark源码剖析 - SparkContext的初始化(八)_初始化管理器BlockManager

    8.初始化管理器BlockManager 无论是Spark的初始化阶段还是任务提交.执行阶段,始终离不开存储体系.Spark为了避免Hadoop读写磁盘的I/O操作成为性能瓶颈,优先将配置信息.计算结 ...

  7. 【c++】必须在类初始化列表中初始化的几种情况

    转自:http://www.cnblogs.com/kaituorensheng/p/3477630.html 1. 类成员为const类型 2. 类成员为引用类型 #include <iost ...

  8. 代码初始化 故事板初始化 xib初始化总结

    对象的初始化有三种方式   // 代码创建 - (id)initWithFrame:(CGRect)frame { if (self = [super initWithFrame:frame]) { ...

  9. Java静态初始化,实例初始化以及构造方法

    首先有三个概念需要了解: 一.静态初始化:是指执行静态初始化块里面的内容. 二.实例初始化:是指执行实例初始化块里面的内容. 三.构造方法:一个名称跟类的名称一样的方法,特殊在于不带返回值. 我们先来 ...

随机推荐

  1. ES的Zen发现机制

    ES的Zen发现机制 Zen发现机制是ElasticSearch默认的发现模块.它提供的是单播发现,但是可被拓展为支持云环境下或者其他形式的发现机制.zen 发现模块集成了其他模块,如在发现期间,节点 ...

  2. 网络请求工具 cURL

    网络请求工具 cURL 2017-08-16 cRUL 是一种命令行工具,作用是发出网络请求,然后得到和提取数据,显示在“标准输出”(stdout)上面. 查看网页源码 1 $ curl baidu. ...

  3. Kotlin Reference (三) Coding Conventions

    most from reference 命名规则 1.使用驼峰式命名规则,尽量避免在命名中使用下划线 2.类型以大写字母开头 3.方法和属性以小写字母开头 4.使用4个空格缩进 5.public的方法 ...

  4. clean-css 安装 使用

    https://github.com/jakubpawlowicz/clean-css-cli https://davidwalsh.name/clean-css

  5. 求二叉树的深度 python

    二叉树有深度和高度两个属性,一个节点的深度指的是从根节点到该节点路径的长度,根节点的深度为1:一个节点的高度指的是从该节点到叶子节点所有路径上包含节点个数的最大值.叶子节点的高度为1,往上节点的高度依 ...

  6. 看完前任三,想起我的前任java女程序员,她曾教会我……

    前任三最近非常火了,票房蹭蹭往上升,昨天也去电影院看了,想起了我的前任,她是一名女程序员,为了让我学好java,她曾经亲自教我Java的算法,学算法是件非常重要的事,在这忍住回忆的悲伤,分享给你们. ...

  7. python2 之 pyh2

    1.功能 pyh作爲基於python的簡易html生成庫,收到了廣大python愛好者(比如說我,當然其他人沒有調查過)的深切喜愛. 簡潔的行文風格繼承了python一貫的作風,可以讓你用簡單的Pyt ...

  8. MPI 学习

    一.编译MPI mpic++ test.cc -o test 二.启动MPI mpiexec -np 10 ./test 三.几个例子 第一个进程向第二个发一个数,第二个进程向第三个进程发送一个数.. ...

  9. c语言符号常量与常变量的区别?

    <blockquote>定义符号常量:#define PI 3.1415926               //注意后面没有分号 定义常变量  :const float PI=3.1415 ...

  10. 很让人受教的提高php代码质量的方法

    1.不要使用相对路径 常常会看到: require_once('../../lib/some_class.php'); 该方法有很多缺点: 它首先查找指定的php包含路径, 然后查找当前目录. 因此会 ...