为什么在Bjarne Stroustrup的书中,构造函数Zlib_init在类Zlib_init中是私有的

Why are the constructor Zlib_init kept private in class Zlib_init in the book by Bjarne Stroustrup

本文关键字:init Zlib 在类 Bjarne Stroustrup 为什么 构造函数      更新时间:2023-10-16

在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;
/  /...
};

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

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

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

构造函数&析构函数private似乎是一个拼写错误
static类成员需要定义才能使用。为了定义静态成员x,构造函数需要是可访问的。否则,链接器将抱怨未定义的引用。

在线样本

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++中通常被称为静态初始化Fiasco

阅读良好:

[10.14]什么是"静态初始化订单惨败">
[10.17]如何防止我的静态数据成员出现"静态初始化顺序惨败"?

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

我只是猜测,但我认为作者把声明精简到了传达他的想法所必需的最低限度。尽管用struct代替class也同样有效,而且在他的书的其他地方,作者在这种情况下使用了省略号(…)。所以我不确定。

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

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