有没有办法在C++中实现单例对象:
(我不太了解我的C++,但是在执行任何代码之前初始化积分和常量静态变量的情况(即,甚至在执行静态构造函数之前 - 它们的值可能已在程序中"初始化")如果是这样的话 - 也许这可以被利用来实现单例互斥体 - 这反过来可以用来保护真正的单例的创建......)
很好,现在我似乎有几个好的答案(羞耻我不能标记2或3作为答案).似乎有两个广泛的解决方案:
c++ singleton construction multithreading lazy-initialization
我一直在阅读有关线程安全的单例模式:
http://en.wikipedia.org/wiki/Singleton_pattern#C.2B.2B_.28using_pthreads.29
它在底部说,唯一安全的方法是使用pthread_once - 这在Windows上不可用.
这是保证线程安全初始化的唯一方法吗?
我在SO上读过这个帖子:
并且似乎暗示了原子操作系统级别的交换和比较功能,我在Windows上假设:
http://msdn.microsoft.com/en-us/library/ms683568.aspx
这可以做我想要的吗?
编辑:我想懒惰的初始化,因为只有一个类的实例.
另一个网站上有人提到在命名空间中使用全局(并且他将单例描述为反模式) - 它如何成为"反模式"?
一般承认的答案:
我已经接受了Josh的回答,因为我正在使用Visual Studio 2008 - 注意:对于未来的读者,如果您不使用此编译器(或2005) - 请勿使用接受的答案!
编辑: 除了return语句之外代码工作正常 - 我收到错误:错误C2440:'return':无法从'volatile Singleton*'转换为'Singleton*'.我应该将返回值修改为易失性Singleton*吗?
编辑:显然const_cast <>将删除volatile限定符.再次感谢Josh.
可能重复:
VC2010是静态init线程安全吗?
我知道gcc和llvm-clang发出代码以线程安全的方式初始化本地静态变量(这允许通过在函数中包装全局静态来逃避静态顺序初始化失败).
然而,这篇msdn博客文章是我在这些情况下可以找到的关于vcc行为的最佳文档,并且声称静态初始化不能是线程安全的,因为本地静态的初始化可以递归地调用相同的作用域.
我不买这个论点 - 如果初始化者依赖于它自己的结果,那显然是编程错误.
因此,鉴于本文来自2004年,gcc和clang可以做到这一点,并且当前的msvc文档是不明确的(声明'分配'到本地静态不是线程安全的,但仅此而已):
在MSVC中,本地静态的初始化现在是线程安全的吗?
如果没有,为什么不呢,因为gcc显然可以这样做,但程序员很难在之后加入.
我如何在MSVC中取消名称?gcc中有abi :: __ cxa_demangle函数.在MSDN中我找到了UnDecorateSymbolName:
http://msdn.microsoft.com/ru-ru/library/windows/desktop/ms681400%28v=vs.85%29.aspx
不幸的是,这个功能甚至不能解开这样的符号:
#include <Windows.h>
#include <DbgHelp.h>
#include <cstdlib>
#include <iostream>
#include <typeinfo>
int main()
{
SymSetOptions(SYMOPT_UNDNAME | SYMOPT_DEFERRED_LOADS);
if (!SymInitialize(GetCurrentProcess(), NULL, TRUE))
{
std::cout << "SymInitialize returned error: " << GetLastError() << '\n';
return EXIT_FAILURE;
}
class Foo {};
Foo instance;
const char* decorated_name = typeid(instance).name();
char undecorated_name[1024];
if (!UnDecorateSymbolName(decorated_name, undecorated_name, sizeof(undecorated_name) / sizeof(*undecorated_name), UNDNAME_COMPLETE))
{
std::cout << "UnDecorateSymbolName returned error: " << GetLastError() << '\n';
return EXIT_FAILURE;
}
std::cout << "Decorated name: " << decorated_name …Run Code Online (Sandbox Code Playgroud) 我不明白为什么当我按“f”时它进入全屏但不退出全屏。在这个方法的开头我已经设置了bool fullscreen = false;
这是我的切换代码:
case 'f': //toggle screenmode
if(!fullscreen){
glutFullScreen();
fullscreen = true;
} else if(fullscreen){
glutReshapeWindow(1200, 900);
glutPositionWindow(0,0);
fullscreen = false;
}
break;
Run Code Online (Sandbox Code Playgroud)