从初始化列表和构造函数谈C的初始化机制_第1页
从初始化列表和构造函数谈C的初始化机制_第2页
从初始化列表和构造函数谈C的初始化机制_第3页
从初始化列表和构造函数谈C的初始化机制_第4页
从初始化列表和构造函数谈C的初始化机制_第5页
已阅读5页,还剩5页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、【深入理解C+】从初始化列表和构造函数谈C+的初始化机制前段时间被人问及“初始化列表和构造有什么区别?”我竟一时语塞,只好回头拿起几本C+的大部头书,打开VS2012和vim开始倒腾。最后总结出如下几点,希望对大家理解C+能有些帮助。(题外话:我认为好的技术书籍和师者对人最大的帮助就是:帮助学者节省时间。)综合而言,C+中类的初始化操作有四个部分组成:初始化列表:所有类非静态数据成员都可以在这里初始化,所有类静态数据成员都不能在这里初始化构造函数体:对于类非静态数据成员:const型成员不能在这里初始化引用型成员不能在这里初始化没有默认构造函数的成员不能在这里初始化对于类静态数据成员:可以在这

2、里修改可修改的静态成员,但静态成员必须已经在类外部初始化类外初始化:除一个特例外,所有类static数据成员必须在这里初始化,特例是类staticconstint数据成员可以在这里初始化,也可以在成员的声明处初始化类中声明时直接赋值:类staticconstint数据成员可以选在这里初始化。直接罗列这样的规则,是我国大多数教科书的展开方式,记得经典的三部曲吗?1)定义2)定理3)例题至于来龙去脉就只能靠我们这些学子的悟性了。何其苦载!事实证明需要理清一些定理和思想的来龙去脉往往需要比这个定理更加广阔的知识和视野,让学生拿着空洞的课本靠领悟?(不要意思,又吐槽了)让我们从一段简单的代码开始:cp

3、pviewplaincopyclassAconstintx;public:A()this-x=1;/*Error!*/;对很多人而言,这是什么直观写法,为什么就错了呢?其实这本质上相当于写:cppviewplaincopyconstintx;x=1;所以我们只能按如下方式声明其初始化:cppviewplaincopyclassAconstintx;public:A():x(1);再来看一段简单的代码:htmlviewplaincopyclassAint&x;public:A(intk)this-x=k;/*Error!*/;同理这这本质上相当于写:cppviewplaincopyint&x;x

4、=k;所以我们只能按如下方式声明其初始化:cppviewplaincopyclassAconstintx;public:A(intk):x(k);有了上面两个简单例子作为引子,我们开始进一步讨论C+初始化的全过程。其实我相信很多人还是怀着这样一些疑问“写在初始化列表里就相当于int&x=k;吗?”且让我们来看看C+类的初始化的全过程:(1)静态成员初始化阶段:所有类的静态成员应该都是在这个阶段初始化的。注意初始化的顺序,就是操作语句的顺序,例如你有一个Test类:cppviewplaincopyintTest:x=2;intTest:y=3;需要注意的是2点,一是初始化语句不再需要static

5、关键字,二是执行顺序就是语句的顺序,这里是先初始化t1,再初始化t2。执行顺序的问题在静态成员是类的时候就关系到构造函数的调用顺序了。另外需要注意的是,这些静态成员的初始化在任何具体实例被创建前就已经完成了。(2)实例初始化列表工作阶段:需要说的是,在用户使用new或者其他方法开始构建实例的时候,第一步首先是向操作系统申请内存,初始化列表是在申请成功后才开始工作的。然后,根据非静态成员的声明顺序开始执行如下操作:.如果该成员没有出现在初始化列表中:)如果是内置非const且非引用类型,不设定初值)如果是const类型,报错,必须在这里给定初值3)如果是引用类型,报错,必须在这里给定初值)如果是

6、class类型,就调用默认构造函数,进行初始化操作.如果该成员出现在初始化列表中:1)如果是内置类型,就按初始化列表指定的值设定初值)如果是const类型,就按初始化列表指定的值设定初值3)如果是引用类型,就按初始化列表指定的值设定初值)如果是class类型,就调用初始化列表指定的构造函数进行初始化操作(3)计算阶段:根据构造函数的函数体进行赋值操作,或者修改操作,在这里,静态和非静态数据都可以赋值和修改下面用一段代码来测试这个过程:cppviewplaincopyclassTest1/*用于测试Test2中含有没有默认构造函数的成员时的情况*/public:inti;Test1(inta):

7、i(a)/*这就取消了Test1的默认构造函数*/;classTest2public:inta;/inta=1;Error:不允许数据成员初始值设定项constintb;staticintc;staticconstintd=4;/正确,这样赋值也是可以的,也可以选在类声明外进行赋值/但是如果不赋值,则程序中没有使用d不出错,使用了就会有linkerror/无法解析的外部命令/staticconstfloatff=4.0;Error:只有静态常量整形数据成员才可以在类中初始化int&e;constint&f;staticint&g;staticconstint&h;/staticconstint

8、&h=x_h;Error:只有静态常量整形数据成员才可以在类中初始化Test1t1;constTest1t2;staticTest1t3;conststaticTest1t4;Test2(intb,inte,intf,Test1t1,Test1t2):b(b),/d(4),Error:d不是类的非静态成员或基类e(e),/如果没有这句,Error:Test2:e没有提供初始化值f(f),t1(t1),/如果没有这句,Error:Test1没有默认构造函数t2(t2)a=1;/b=2;/Error:表达式必须是可修改的左值,b是左值,不能修改c=3;/d=4;/Error:表达式必须是可修改的左

9、值,d是左值,但不能修改;/intTest2:a=1;/Error:非静态数据成员不能在其类的外部定义/intTest2:b=2;/Error:非静态数据成员不能在其类的外部定义intTest2:c=3;/如果没有这句,会出现无法解析的外部符号public:staticintA:c/intTest2:d=4;/Error:int与声明constint不兼容/intconstTest2:d=4;/和在类声明里面直接写赋值等价intx_g=5;/*这个全局变量主要用户后续的静态成员赋值*/intx_h=6;/*这个全局变量主要用户后续的静态成员赋值*/Test1x_t3(7);/*这个全局变量主要

10、用户后续的静态成员赋值*/Test1x_t4(8);/*这个全局变量主要用户后续的静态成员赋值/int&Test2:g=x_g;constint&Test2:h=x_h;Test1Test2:t3=x_t3;constTest1Test2:t4=x_t4;前面讲了这么多具体的细节,我个人建议按如下简化规则来记忆:1)所有static成员变量在类外初始化(不管它是const,是引用,还是没默认构造函数的对象)2)普通成员变量,是const,是引用,是没默认构造函数的,必须在初始化列表初始化3)普通成员变量,需要复杂运算的初始化变量,应该在构造函数内初始化,否则尽量在初始化列表中初始化。另外补充2

11、个小点:1)初始化列表的使用可能提高性能cppviewplaincopyclassTest3public:inta;Test3()a=0;puts(Test3constructor);Test3(Test3&t3)this-a=t3.a;puts(Test3copyconstructor);Test3&operator=(Test3&t)puts(Test3assignoperator);this-a=t.a;return*this;Test3();classTest4public:Test3t3;/Test4(Test3&t3):t3(t3)/这种方式和下面的方式有相同的效果,不同的效率/Test4(Test3&t3)this-t3=t3;(2)成员是按照他们在类中出现的顺序进行初始化的,而不是按照他们在初始化列表出现的顺序初始化的参考如下代码cppviewplaincopystructfoointi;intj;foo(intx):i(x),j(i);/ok,先初始化i,后初始化j;再看下面的代码cppviewplaincopystructfoointi;intj;foo(intx)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论