В книге Бьярна Страуструпа «Язык программирования 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 книги.
Почему автор сохраняет конструктор и деструктор в качестве закрытых членов?
Конструктор & деструктор 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
код все еще сталкивается с другой проблемой.
Проблема обычно известна как Статическая инициализация Fiasco в C ++.
Хорошо для чтения:
[10.14] Что такое «фиаско статического порядка инициализации»?
[10.17] Как предотвратить фиаско статического порядка инициализации для моих статических членов данных?
Почему автор сохраняет конструктор и деструктор в качестве закрытых членов?
Я только догадываюсь, но я предполагаю, что автор сократил декларацию до минимума, необходимого для передачи своей идеи. Хотя struct
вместо class
работал бы так же хорошо, и в других местах своей книги автор использует многоточие (…) в таких случаях. Так что я не уверен.
И почему этот метод не будет работать, если мы будем использовать его в программе, состоящей из отдельно скомпилированных модулей?
Конструктор статического объекта будет запущен раньше main
так что если вы используете только Zlib
в материале, вызванном из main
, все работает хорошо. Проблемы начинаются, если какой-то другой статический объект в каком-либо другом модуле компиляции пытается использовать Zlib
в своем конструкторе. Нет никаких гарантий относительно порядка выполнения этих двух конструкторов, так что вы можете получить код, пытающийся использовать неинициализированный код. Zlib
учебный класс.