【问题标题】:object initialization对象初始化
【发布时间】:2011-03-16 16:30:57
【问题描述】:

在《The C++ Language》一书中,作者声称

有时,当您设计一个库时,有必要或者只是为了方便,发明一种具有构造函数和析构函数的类型,其唯一目的是初始化和清理。这种类型只能使用一次:分配一个静态对象,以便调用构造函数和析构函数。

我对这句话所指的场景感兴趣?或者这个陈述如何帮助软件设计?

书中还举了一个例子

class Zlib_init{
    Zlib_init( );
    ~Zlib_init( );
};

class Zlib{
    static Zlib_init x;
}

这本书说

不幸的是,不能保证这样的对象在第一次使用前被初始化,在由单独编译的单元组成的程序中最后一次使用后被销毁。

为什么会发生这种情况?

感谢您的澄清。

【问题讨论】:

  • 你可以保证这样的对象会在 main 被调用之前被创建并且在 main 返回之后被销毁。因此,您可能会想说“但是,但是……一切都很好”。不幸的是,您的程序中可能有一个不同的静态对象,它也使用 Zlib_init 对象,并且 C++ 语言不保证该对象是否会在此对象或任何其他对象之前或之后被创建或销毁,只要它们在不同的编译单元。所以,措辞可能有点迂腐,但它是 100% 正确的。 (好吧,反正它是正确的,因为它是 Stroustrup)。

标签: c++ class constructor initialization


【解决方案1】:

C++ 标准没有指定创建静态对象的顺序。因此,如果您需要静态对象中的一些层次结构,则需要它们相互依赖(例如,一个应该是另一个的成员)。书中的构造保证了这种行为。

例如,一个假设的游戏引擎需要声音和图形引擎才能工作,如果您在单独的编译单元中将它们声明为静态对象,并从另一个编译单元中使用它们,除非您按照这种方式编写代码,否则无法保证它不会失败你指定了。

请参阅C++ faq 条目以了解您问题的第二部分。

【讨论】:

  • 在同一个编译单元中,它们是按照定义(不是声明)的顺序构造的。问题是当它们分布在多个单元中时......
  • 谢谢,我已经解决了。
【解决方案2】:

不幸的是,不能保证这样的对象在第一次使用前被初始化,在由单独编译的单元组成的程序中最后一次使用后被销毁。

例如,如果您在一个模块中的static 存储上具有您的类的实例,并且希望从另一个模块中static 存储上的另一个类的构造函数中使用它。在这种情况下,您暗示第一个实例将在第二个实例之前初始化。但是,如果实例是在单独的模块中定义的,则语言无法指定此顺序。

有时,当您设计一个库时,有必要或者只是为了方便,发明一种具有构造函数和析构函数的类型,其唯一目的是初始化和清理。这种类型只能使用一次:分配一个静态对象,以便调用构造函数和析构函数。

当您使用需要初始化和完成调用的 3-rd 部分库时,这很有用。例如,WinSock 2 需要 WSAStartup 才能调用其他 WSA 函数,并且当您在进程中使用完 WinSock 时需要 WSACleanup。如果您有此类类的静态实例,在构造函数中调用 WSAStartup,在析构函数中调用 WSACleanup,您应该能够在程序的其他位置使用 WSA 函数(其他静态对象的构造函数/析构函数除外)。

【讨论】:

    猜你喜欢
    • 2013-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多