C++有个令人头痛的点是会出现一些极其复杂的变量声明,比如:
string(const** f(int, void (*const p)(int)))(char[]);2025/9/1大约 2 分钟
C++有个令人头痛的点是会出现一些极其复杂的变量声明,比如:
string(const** f(int, void (*const p)(int)))(char[]);平时我们经常会看到一些临时变量,这些变量只定义了一次且并没有被使用,通常这些变量是被用来管理或分析某个作用域。最近突然好奇:既然这些变量不会被使用,为什么要给这些变量定义名字?故浅浅探讨了一下。
匿名对象是指没有变量名的临时对象,通常是表达式直接产生的对象,只能在创建它的语句中使用一次,生命周期很短。
具名对象是通过变量名定义并保存的对象,可以被多次引用、访问、传参等,生命周期更长,控制权更强。
众所周知,根据创建时机单例模式分为懒汉式和饿汉式,根据线程是否安全分为线程安全和线程不安全。
最近看Cherno的一个讲解视频,对于单例模式有了一个新的认识。Cherno认为,给单例提供一个随时随地的访问接口不利于游戏引擎这种底层框架的设计,会打乱程序的树状架构。
对于下面这个单例实现方式,根据静态对象的构造时机以及C++11后局部静态变量在第一次被访问时初始化是线程安全的特性,很容易得到这是饿汉式线程安全的一种实现。但这种方式不能直观地显式创建和销毁单例对象,尤其是当应用程序有多个单例,而且单例间存在依赖关系,需要特定的创建和销毁顺序。
最近发现C++里面可以通过实现lock、unlock两个方法实现自定义锁,因此去看了下MSVC中std::lock_guard的C++11实现。lock_guard通过在构造函数中调用lock函数上锁、在unlock函数解锁。
_EXPORT_STD template <class _Mutex>
class _NODISCARD_LOCK lock_guard { // class with destructor that unlocks a mutex
public:
    using mutex_type = _Mutex;
    explicit lock_guard(_Mutex& _Mtx) : _MyMutex(_Mtx) { // construct and lock
        _MyMutex.lock();
    }
    lock_guard(_Mutex& _Mtx, adopt_lock_t) noexcept // strengthened
        : _MyMutex(_Mtx) {} // construct but don't lock
    ~lock_guard() noexcept {
        _MyMutex.unlock();
    }
    lock_guard(const lock_guard&)            = delete;
    lock_guard& operator=(const lock_guard&) = delete;
private:
    _Mutex& _MyMutex;
};