一、 直接初始化和复制初始化
1.定义:直接初始化使用"( )"符号,如:string s("hello");复制初始化使用"="符号,如:string s="hello".
2.区别:对于内置类型,直接初始化和复制初始化没有差别:其操作都是"提供一个值,并且把这个值复制到新定义的对象中"(《C++ Primer》).
对于类类型,直接初始化根据参数类型调用相应构造函数,复制初始化调用拷贝构造函数,对于以下初始化:
String s1("hello");//String是自定义的字符串类 String s2="hello";
s1的初始化调用String的String(char*)构造函数直接对s1进行初始化,s2的初始化则是先调用String(char*)构造函数构造一临时对象,再调用拷贝构造函数String(const String&)对s2进行初始化.也就是说,如果复制初始化的参数不是同类型的数值,就会多一次临时对象的构造和析构成本.
(如果实验验证,会发现两行代码都调用String(char*)构造函数,这是因为大多数编译器都实行RVO/NRVO((具名)返回值优化)从而避免了临时对象的产生,但了解实际过程,写出不依赖于编译器优化的代码也是很重要的)
二、全局/静态变量(对象)的初始化
(参考自:http://bbs.csdn.net/topics/390527051?page=1
http://www.tuicool.com/articles/QRBF3qN)
1.全局变量的初始化分为静态初始化和动态初始化:
静态初始化:编译期进行的初始化,所谓编译期进行的初始化,即在编译期直接将数据放在程序虚拟地址空间的数据段中,因此静态初始化在程序加载到内存时完成.静态初始化又分为 zero-initialization(零初始化)和constant initialization(常量初始化),zero-inltilization指的是对于没有指明初始化式的全局对象,就由编译器用0初始化,并存储在程序的.BSS段中(由于初始化为0,因此实际上不需要占用空间,在加载到内存时直接初始化为0即可,所以.BSS段的段内容长度为0),const inilitization指的是对于指明常量初始化式的全局对象, 就由指明的初始化式进行初始化.
所有全局对象都会发生静态初始化:指明常量初始化式的进行constant initilization,未指明初始化式的进行zero-initilization,指明非常量初始化式的也会进行zero-initilization(然后在运行期进行动态初始化)
动态初始化:运行时进行的初始化,所谓运行时进行的初始化,不是指在main函数中,事实上,操作系统加载完程序之后,会有默认入口(比如 mainCRTStartup(void) /wmainCRTStartup(void)/WinMainCRTStartup(void)/wWinMainCRTStartup(void)等),visual C++下是mainCRTStartup(void),mainCRTStartup的任务之一就是进行相关初始化操作,然后调用main函数,因此动态初始化发生在mainCRTStartup执行中,main函数执行前.
指明非常量初始化式的全局对象进行动态初始化,包括需要调用函数的和用其他全局对象初始化的.例如string s,int a=b;
举例:
int a; //静态初始化为0 struct Point{ int x; int y; } temp={1,2};//静态初始化x,y为1,2 int b=a;//静态初始化为0,然后动态初始化为a,稍后会说明只有c++允许 string s;//先进行动态初始化,然后调用默认构造函数进行动态初始化