您的位置:首页 > 编程语言 > C语言/C++

C/C++:对象初始化相关

2015-09-28 02:23 579 查看
一、 直接初始化和复制初始化

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;

举例:

// global.cpp

#include "global.h"

// need to ensure memory alignment??
static char g_dummy[sizeof(X)];

static X& x = reinterpret_cast<X&>(g_dummy);

int initializer::s_counter_ = 0;

void initializer::init()
{
new(&x) X;
}

void initializer::clean()
{
(&x)->~X();
}


View Code
由于x只是一个引用,编译器不会调用x的构造函数和析构函数.

至此,这个方案已经比较完美,但它还需要一个成功运行的条件:所有引用x的地方都会include头文件global.h(从而保证s_init_val已定义),"如果某一个全局变量 y 的初始化函数 里没有直接引用 x, 而是间接调用了另一个函数 foo,再通过 foo 引用了 x,此时就可能出错了,因为 y 所在的编译单元里可能并没有直接引用 x,因此很有可能就没有 include 头文 件 global.h,那么 y 的初始化就很有可能发生在 x 之前",在此情况下,此方案没能发挥作用.

"这个问题在 gcc c++ 的标准库里也没有得到解决,有兴趣的可以看看这个讨论".
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: