- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
人们到处都在使用单例。最近从 stackoverflow 上读到一些线程,认为在 C++ 中应该避免单例,但不清楚为什么会这样。
有些人可能会担心未删除指针的内存泄漏,异常之类的东西会跳过内存回收代码。但是 auto_ptr 会解决这个问题吗?
最佳答案
一般来说,正如另一个答案中提到的,您应该避免使用可变的全局数据。它引入了跟踪代码副作用的困难。
但是您的问题是专门针对 C++ 的。例如,您可以拥有值得在单例中共享的全局不可变数据。具体而言,在 C++ 中,几乎不可能在多线程环境中安全地初始化单例。
多线程环境
您可以使用“首次使用时构造”习惯用法来确保单例在需要时正确初始化:http://www.parashift.com/c++-faq-lite/static-init-order.html .
但是,如果您有 2 个(或更多)线程都在同一时间第一次尝试访问单例,会发生什么情况?如果共享的不可变数据是您的 calculateSomeData
线程所需的数据,并且您同时初始化其中的几个线程,那么这种情况并不像看起来那么牵强。
阅读上面链接的 C++ FAQ Lite 中的讨论,您首先会发现这是一个复杂的问题。添加线程会使它变得更加困难。
在 Linux 上,编译器使用 gcc 为您解决了这个问题 - 静态变量在互斥体中初始化并且代码对您来说是安全的。这是一个增强,标准不需要这样的行为。
在 MSVC 中,编译器不为您提供此实用程序,您会遇到崩溃。您可能会想“没关系,我会在第一次使用初始化时放置一个互斥体!”然而,互斥量本身也存在完全相同的问题,它本身需要是静态的。
确保您的单例对线程使用安全的唯一方法是在任何线程启动之前在程序中尽早初始化它。这可以通过一个技巧来实现,该技巧会导致在调用 main 之前初始化单例。
依赖其他单例的单例
这个问题基本上可以通过首次使用时的构造来解决,但是如果您在初始化任何线程之前遇到初始化它们的问题,则可能会引入新的问题。
跨平台兼容性
如果您计划在多个平台上使用您的代码并编译共享库,则可能会遇到一些问题。因为没有指定 C++ ABI 接口(interface),每个编译器和平台处理全局静态的方式不同。例如,除非在 MSVC 中显式导出符号,否则每个 DLL 都将有自己的单例实例。在 Linux 上,单例将在共享库之间隐式共享。
关于c++ - 为什么要避免在 C++ 中使用单例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25345645/
我最近购买了《C 编程语言》并尝试了 Ex 1-8这是代码 #include #include #include /* * */ int main() { int nl,nt,nb;
早上好!我有一个变量“var”,可能为 0。我检查该变量是否为空,如果不是,我将该变量保存在 php session 中,然后调用另一个页面。在这个新页面中,我检查我创建的 session 是否为空,
我正在努力完成 Learn Python the Hard Way ex.25,但我无法理解某些事情。这是脚本: def break_words(stuff): """this functio
我是一名优秀的程序员,十分优秀!