谁负责销毁块作用域的静态 Singleton 实例?
Who is responsible for destructing the block scoped static Singleton instance?
我无法理解下面的程序是如何编译成功的。
class SomeClass {
public: /** Singleton **/
static SomeClass &instance() {
static SomeClass singleInstance;
return singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
SomeClass &operator=(const SomeClass&) = delete;
~SomeClass() {}
};
int main()
{
SomeClass::instance();
// SomeClass::instance().~SomeClass(); // Compiles if destructor was public
return 0;
}
- 谁负责调用Singleton的析构函数
实例?
- 底层机制如何访问私有方法?
很快,在构造过程中,编译器将析构函数保存到将在程序最后调用的函数列表中。最后,函数列表,包括析构函数,一个一个被调用,安全销毁。
底层机制
该机制的核心是C标准库提供的exit()
和atexit(..)
函数。在程序编译期间,编译器会在您的 block-scoped 静态变量周围注入一些其他代码。伪表示如下。
static SomeClass& instance() {
static SomeClass singleInstance;
/*** COMPILER GENERATED ***/
// Guard variable generated by the compiler
static bool b_isConstructed = false;
if(!b_isConstructed)
ConstructInstance(); // Constructs the Singleton instance
b_isConstructed = true;
// Push destructor to the list of exit functions
atexit(~SomeClass());
}
/*** COMPILER GENERATED ***/
return singleInstance;
};
这里的重点是调用 atexit(~SomeClass())
并将析构函数注册到 exit()
函数的自动调用列表中,当您从 [=15] return 时隐式调用该函数=].由于使用函数指针而不是直接引用私有析构函数方法,因此跳过了访问说明符保护机制。
我无法理解下面的程序是如何编译成功的。
class SomeClass {
public: /** Singleton **/
static SomeClass &instance() {
static SomeClass singleInstance;
return singleInstance;
};
private:
SomeClass() = default;
SomeClass(const SomeClass&) = delete;
SomeClass &operator=(const SomeClass&) = delete;
~SomeClass() {}
};
int main()
{
SomeClass::instance();
// SomeClass::instance().~SomeClass(); // Compiles if destructor was public
return 0;
}
- 谁负责调用Singleton的析构函数 实例?
- 底层机制如何访问私有方法?
很快,在构造过程中,编译器将析构函数保存到将在程序最后调用的函数列表中。最后,函数列表,包括析构函数,一个一个被调用,安全销毁。
底层机制
该机制的核心是C标准库提供的exit()
和atexit(..)
函数。在程序编译期间,编译器会在您的 block-scoped 静态变量周围注入一些其他代码。伪表示如下。
static SomeClass& instance() {
static SomeClass singleInstance;
/*** COMPILER GENERATED ***/
// Guard variable generated by the compiler
static bool b_isConstructed = false;
if(!b_isConstructed)
ConstructInstance(); // Constructs the Singleton instance
b_isConstructed = true;
// Push destructor to the list of exit functions
atexit(~SomeClass());
}
/*** COMPILER GENERATED ***/
return singleInstance;
};
这里的重点是调用 atexit(~SomeClass())
并将析构函数注册到 exit()
函数的自动调用列表中,当您从 [=15] return 时隐式调用该函数=].由于使用函数指针而不是直接引用私有析构函数方法,因此跳过了访问说明符保护机制。