Apollo Singleton Macro
#ifndef CYBER_COMMON_MACROS_H_
#define CYBER_COMMON_MACROS_H_
#include <iostream>
#include <memory>
#include <mutex>
#include <type_traits>
#include <utility>
#include "cyber/base/macros.h"
DEFINE_TYPE_TRAIT(HasShutdown, Shutdown)
template <typename T>
typename std::enable_if<HasShutdown<T>::value>::type CallShutdown(T *instance) {
  instance->Shutdown();
}
template <typename T>
typename std::enable_if<!HasShutdown<T>::value>::type CallShutdown(
    T *instance) {
  (void)instance;
}
// There must be many copy-paste versions of these macros which are same
// things, undefine them to avoid conflict.
#undef UNUSED
#undef DISALLOW_COPY_AND_ASSIGN
#define UNUSED(param) (void)param
#define DISALLOW_COPY_AND_ASSIGN(classname) \
  classname(const classname &) = delete;    \
  classname &operator=(const classname &) = delete;
#define DECLARE_SINGLETON(classname)                                      \
public:                                                                  \
  static classname *Instance(bool create_if_needed = true) {              \
    static classname *instance = nullptr;                                 \
    if (!instance && create_if_needed) {                                  \
      static std::once_flag flag;                                         \
      std::call_once(flag,                                                \
                    [&] { instance = new (std::nothrow) classname(); }); \
    }                                                                     \
    return instance;                                                      \
  }                                                                       \
                                                                          \
  static void CleanUp() {                                                 \
    auto instance = Instance(false);                                      \
    if (instance != nullptr) {                                            \
      CallShutdown(instance);                                             \
    }                                                                     \
  }                                                                       \
                                                                          \
private:                                                                 \
  classname();                                                            \
  DISALLOW_COPY_AND_ASSIGN(classname)
#endif  // CYBER_COMMON_MACROS_H_
细节分析
- 
为了能够让程序员显式的禁用某个函数,C++11 标准引入了一个新特性:"=delete"函数。程序员只需在函数声明后上“=delete;”,就可将该函数禁用。 class X3 { public: X3(); X3(const X3&) = delete; // 声明拷贝构造函数为 deleted 函数 X3& operator = (const X3 &) = delete; // 声明拷贝赋值操作符为 deleted 函数 };
- 
在多线程编程中,有一个常见的情景是某个任务只需要执行一次。在C++11中提供了很方便的辅助类once_flag,call_once。 #include <iostream> #include <thread> #include <mutex> std::once_flag flag; void do_once() { //也可以写在这里。要记住static,一旦flag被销毁了就不能保证只执行一次了 //static std::once_flag flag; std::call_once(flag, [](){ std::cout << "Called once" << std::endl; }); } int main() { std::thread t1(do_once); std::thread t2(do_once); std::thread t3(do_once); std::thread t4(do_once); t1.join(); t2.join(); t3.join(); t4.join(); } //可以看到,只会输出一行Called once
 
      