分享

More C++ Idioms/Attach by Initialization

 dongtongtong 2015-05-29
Attach by Initialization
通过初始化挂接
Intent
Attach a user-defined object to a framework before program execution begins.
在程序执行之前,给一个框架挂接一个用户定义类型的对象
Motivation
Certain application programming frameworks, such as GUI frameworks (e.g., Microsoft MFC) and object request brokers (e.g., some CORBA implementations) use their own internal message loops (a.k.a. event loops) to control the entire application. Application programmers may or may not have the freedom to write the application-level main function. Often, the main function is buried deep inside the application framework (e.g, AfxWinMain in case of MFC). Lack of access to main keeps programmers from writing application-specific initialization code before the main event loop begins. Attach-by-initialization idiom is a way of executing application-specific code before the execution of framework-controlled loop begins.
某些应用程序编程框架,比如GUI框架(MFC)和对象请求代理使用他们自己内部的消息循环控制整个应用程序。应用程序员可能有或没有自由来写应用级的主函数。通常,主函数被深埋在应用框架之下。缺少对主函数的访问权限阻碍了程序员编写特定的应用程序初始化代码在主事件循环之前。Attach-by-initialization idiom是在框架循环开始之前运行应用特定代码的一种方法。
Solution and Sample Code
In C++, global objects and static objects in global namespace are initialized before main begins execution. These objects are also known as objects of static storage duration. This property of objects of static storage duration can be used to attach an object to a system if programmers are not allowed to write their own main function. For instance, consider the following (smallest possible) example using Microsoft Foundation Classes (MFC).
在C++中,全局对象和在全局空间的静态对象在main开始执行之前被初始化。这些对象被称为静态存储周期的对象。对象的静态存储周期属性可以被用来给系统挂接一个对象。如果程序员不被允许写他们自己的main函数。例如思考下面的使用MFC的例子。
///// File = Hello.h
class HelloApp: public CWinApp
{
public:
    virtual BOOL InitInstance ();
};
///// File = Hello.cpp
 
#include <afxwin.h>
#include "Hello.h"
HelloApp myApp; // Global "application" object
BOOL HelloApp::InitInstance ()
{
  m_pMainWnd = new CFrameWnd();
  m_pMainWnd->Create(0,"Hello, World!!");
  m_pMainWnd->ShowWindow(SW_SHOW);
  return TRUE;
}
The above example creates a window titled "Hello, World!" and nothing more. The key thing to note here is the global object myApp of type HelloApp. The myApp object is default-initialized before the execution of main. As a side-effect of initializing the objects, the constructor of CWinApp is also called. The CWinApp class is a part of the framework and invokes constructors of several other classes in the framework. During the execution of these constructors, the global object is attached to the framework. The object is later on retrieved by AfxWinMain, which is an equivalent of regular main in MFC. The HelloApp::InitInstance member function is shown just for the sake of completeness and is not an integral part of the idiom. This function is called after AfxWinMain begins execution.
上面的例子创建了一个标题是"Hello,World"的一个窗体。需要注意的关键的地方是类型是HelloApp的全局对象myApp。myApp对象被默认初始化在main执行之前。
初始化对象的副作用是,CWinApp的构造函数也被调用。CWinApp这个类是框架的一部分并且唤起在框架中的其他几个类。在这些构造函数执行期间,全局对象被挂接到框架。这个对象之后被检索通过AfxWinMain,在MFC中等同于main显示HelloApp::InitInstance()成员函数这是为了完整性而不是习语的一部分。这个函数被调用之后AfxWinMain开始执行。                                                             
Global and static objects can be initialized in several ways: default constructor, constructors with parameters, assignment from a return value of a function, dynamic initialization, etc.
全局和静态对象可以被初始化以几种方式:默认构造函数,带参数的构造函数,赋值从一个返回值的函数,动态初始化等。
Caveat
警告
In C++, objects in the same compilation unit are created in order of definition. However, the order of initialization of objects of static storage duration across different compilation units is not well defined. Objects in a namespace are created before any function/variable in that namespace is accessed. This may or may not be before main. Order of destruction is the reverse of initialization order but the initialization order itself is not standardized. Because of this undefined behavior, static initialization order problem comes up when a constructor of a static object uses another static object that has not been initialized yet. This idiom makes it easy to run into this trap because it depends on a object of static storage duration.

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多