关闭

C++程序员们,快来写最简洁的单例模式吧

发表于:2015-1-13 09:56

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:老司机    来源:51Testing软件测试网采编

  因此,在有了C++11后我们就可以正确的跨平台的实现DCL模式了,代码如下:
  1 atomic<Widget*> Widget::pInstance{ nullptr };
  2 Widget* Widget::Instance() {
  3     if (pInstance == nullptr) {
  4         lock_guard<mutex> lock{ mutW };
  5         if (pInstance == nullptr) {
  6             pInstance = new Widget();
  7         }
  8     }
  9     return pInstance;
  10 }
  C++11中的atomic类的默认memory_order_seq_cst保证了3、6行代码的正确同步,由于上面的atomic需要一些性能上的损失,因此我们可以写一个优化的版本:
  1 atomic<Widget*> Widget::pInstance{ nullptr };
  2 Widget* Widget::Instance() {
  3     Widget* p = pInstance;
  4     if (p == nullptr) {
  5         lock_guard<mutex> lock{ mutW };
  6         if ((p = pInstance) == nullptr) {
  7             pInstance = p = new Widget();
  8         }
  9     }
  10     return p;
  11 }
  但是,C++委员会考虑到单例模式的广泛应用,所以提供了一个更加方便的组件来完成相同的功能:
  1 static unique_ptr<widget> widget::instance;
  2 static std::once_flag widget::create;
  3 widget& widget::get_instance() {
  4     std::call_once(create, [=]{ instance = make_unique<widget>(); });
  5     return instance;
  6 }
  可以看出上面的代码相比较之前的示例代码来说已经相当的简洁了,但是!!!有是但是!!!!在C++memory model中对static local variable,说道:The initialization of such a variable is defined to occur the first time control passes through its declaration; for multiple threads calling the function, this means there’s the potential for a race condition to define first.因此,我们将会得到一份最简洁也是效率最高的单例模式的C++11实现:
  1 widget& widget::get_instance() {
  2     static widget instance;
  3     return instance;
  4 }
  用Herb Sutter的话来说这份代码实现是“Best of All”的。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号