控制静态初始化的顺序

ZDNet软件频道 时间:2004-02-13 作者:ZDNet China |  我要评论()
本文关键词:cpptips
这种技术依赖使用全局对象,这些全局对象的构建器从概念上说是在main()函数开始执行之前开始执行的。一个读者提醒我,这个技术可能会遇到的一个潜在的问题。
本文译自Builder.com,未经许可请勿转载

这种技术依赖使用全局对象,这些全局对象的构建器从概念上说是在main()函数开始执行之前开始执行的。一个读者提醒我,这个技术可能会遇到的一个潜在的问题。

在标准C++中,如果仅仅在单独的单元中声明对象,那么使用静态存储类型来初始化对象的顺序并没有被确定。也就是说,如果,举个例子,如果一个对象A的构造器使用由对象B的一个非静态成员函数返回的值,这样,对象B就必须在对象A建立之前被创建。但是如果A和B在两个独立的资源文件中被定义,就没有这样的要求了。

有一个简单的解决这个问题的方法:使用局部静态对象来替换每一个全局对象,然后将这个局部对象封装到一个功能函数中去。使用这种方法,客户就可以通过函数调用来访问这个对象。当函数第一次执行的时候,它的局部静态对象就被创建了。因此,在这种情况下,构件对象的顺序就依赖于你先调用哪一个函数。为了确保B在A之前被创建,调用那个第一个定义B的函数。这里有一个完整的例子,可以参照一下:

//文件 A.h

struct A

{

 explicit A(int id) : n (id){}

private:

 int n;

};

//文件 B.h

struct B //B必须要在A之前被创建

{

 B() : timer_id(6) {}

 int getId() const {return timer_id;}

private:

 int timer_id;

};

 

//文件 module1.cpp

#include "B.h"

B& get_b() //取代使用全局对象

{

 static B b; //初始化第一个调用函数get_b()

 return b;

}

//文件 module2.cpp

#include "A.h"

B& get_b();

A a(get_b().getId());//当执行get_b的时候b就被创建了

A的创建器是通过调用函数get_b()来获得的,这个函数首先创建一个B类型的对象,并返回信息。这个信息用于调用函数getId(),这个函数的结果就会被传递给A的创建器。

注意:这个技术不适宜用在多线程环境下。但是单线程应用程序和使用同步模型的程序可以使用它,它将是非常高效的。

作者:Danny Kalev,系统分析员和软件工程师,具有14年研究C++和面向对象设计的经历。



责任编辑:李宁

欢迎评论投稿

百度大联盟认证黄金会员Copyright© 1997- CNET Networks 版权所有。 ZDNet 是CNET Networks公司注册服务商标。
中华人民共和国电信与信息服务业务经营许可证编号:京ICP证010391号 京ICP备09041801号-159
京公网安备:1101082134