3

在 Bjarne Stroustrup 的《C++ 编程语言》一书中,作者说:

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

 class  Zlib_init
{
    Zlib_init() ; //get Zlib ready for use
   ~Zlib_init()  ; //clean up after Zlib
};
Class Zlib
{
   static  Zlib_init   x;
   /  /...
};

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

为什么作者将构造函数和析构函数保留为私有成员?如果我们在由单独编译的单元组成的程序中使用它,为什么这种方法不起作用?它不需要定义成员x来调用构造函数Zlib_init()和析构函数~Zlib_init()吗?那么这个方法有什么用呢?它在本书的第 10.4.9 节中。

4

2 回答 2

8

为什么作者将构造函数和析构函数保留为私有成员?

构造函数和析构函数private似乎是一个错字。需要定义
类成员才能使用它们。为了定义静态成员,构造函数需要可访问。如果不是,链接器将抱怨未定义的引用。 staticx

在线样品

class  Zlib_init 
{    
   Zlib_init() ; //get Zlib ready for use  
  ~Zlib_init()  ; //clean up after Zlib 
   public:
     int j;
};
class Zlib 
{  
   public:  
   static  Zlib_init   x;    
}; 

Zlib_init Zlib::x;

int main()
{
    Zlib::x.j = 10;

    return 0;
}

输出:

prog.cpp:3: error: ‘Zlib_init::Zlib_init()’ is private     
prog.cpp:14: error: within this context      
prog.cpp: In static member function ‘static void Zlib::__static_initialization_and_destruction_0(int, int)’:     
prog.cpp:4: error: ‘Zlib_init::~Zlib_init()’ is private     
prog.cpp:14: error: within this context     

如果我们在由单独编译的单元组成的程序中使用它,为什么这种方法不起作用?

如果您通过创建构造函数和析构函数public或通过Zlib类的朋友来Zlib_init修复上面提到的错字,代码仍然面临另一个问题。
这个问题通常被称为C++ 中的静态初始化惨败

好读:

[10.14] 什么是“静态初始化命令惨败”?
[10.17] 如何防止我的静态数据成员出现“静态初始化顺序失败”?

于 2012-10-05T06:36:57.767 回答
1

为什么作者将构造函数和析构函数保留为私有成员?

我只是猜测,但我认为作者将声明剥离到了传达他的想法所需的最低限度。尽管用 astruct代替 aclass也可以,但在他书中的其他地方,作者在这种情况下使用了省略号 (...)。所以我不确定。

如果我们在由单独编译的单元组成的程序中使用它,为什么这种方法不起作用?

静态对象的构造函数会在之前运行main,所以如果你只Zlib在调用 from 的东西中使用main,一切都会很好。如果其他编译单元中的其他静态对象尝试Zlib在其构造函数中使用,问题就会开始。无法保证这两个构造函数的执行顺序,因此您可能会遇到一些尝试使用未初始化Zlib类的代码。

于 2012-10-05T07:04:35.630 回答