为什么在Bjarne Stroustrup的书中,构造函数Zlib_init在类Zlib_init中是私有的
Why are the constructor Zlib_init kept private in class Zlib_init in the book by Bjarne Stroustrup
在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
类。
- 为char数组调整zlib-zpipe
- 基于boost的程序的静态链接——zlib问题
- GCC对可能有效的代码抛出init list生存期警告
- 为什么 zlib 放气初始化调用一次不起作用?
- GLEW/GLUT:调用init并创建一个窗口后,取消初始化并重新初始化?
- 将 out/in out 参数与 if/switch 的 init 语句一起使用
- 使用 std::ios_base::Init 正确初始化全局变量
- 安装 zlib 库仍然丢失错误
- ZLib GZIP Returning Z_BUF_ERROR(-5)
- 仅在 zlib c++ 库中强制动态编码
- Pybind11: init<> with lambda
- 为什么别名声明不是有效的 init 语句(/simple-declaration)?
- zlib 膨胀在使用小缓冲区时会损坏
- 结构 init:字符**类型的标量初始值设定项两边的大括号
- 简单的安卓二进制崩溃与zlib
- 为什么基于范围类型的大括号上循环init列表是非法的c++
- zlib 添加的各种类型的目的是什么,我如何使用它们?
- boost zlib filter 在 Windows 中不起作用
- 是否可以使用"if constexpr"来声明具有不同类型和init-expr的变量
- 解压缩串联的 zlib 流而不读取下一个字节