几种继承方式

  • public: 该成员可以在任何地方被访问(类内部、派生类中、类外部的任何代码)。
  • protected: 该成员可以在类内部和其派生类中被访问,但不能在类外部被直接访问。
  • private: 该成员只能在类内部被访问,派生类和类外部都不能直接访问。

当你使用 class Derived : <继承方式> Base 时,<继承方式> 就是 publicprivateprotected。这个继承方式会 修改 基类成员在派生类中的访问权限。

核心规则:

派生类中成员的最终访问权限 = min(继承方式, 基类成员原访问权限)

image-20251016143604720

智能指针的用法

// 冗长
std::unique_ptr<HaloExtension> ptr{new HaloExtension()};

// 简洁
auto ptr = std::make_unique<HaloExtension>();

// 大致对应的简洁实现(非官方实现)
template<typename T, typename... Args>
std::unique_ptr<T> make_unique(Args&&... args) {
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}

锁的智能释放

原理

利用 C++ 的“构造函数自动调用”和“析构函数在对象离开作用域时自动调用”的特性,把“加锁”和“解锁”绑定到一个局部对象的生命周期上。

头文件 #include <mutex>

  1. lock_guard
class Counter {
private:
    int count_ = 0;
    std::mutex mtx_;

public:
    void increment() {
        std::lock_guard<std::mutex> lock(mtx_);
        ++count_;
    }

    int get() const {
        std::lock_guard<std::mutex> lock(mtx_);
        return count_;
    }
};
  1. unique_lock,根据构造函数的参数,有多种不同的行为,unique_lock 相较于 lock_guard,其更加灵活,可以手动加锁和释放。

    image-20251016201945966

std::mutex mtx;
std::condition_variable cv;
bool ready = false;

void waitForReady() {
    std::unique_lock<std::mutex> lock(mtx);
    // 自动解锁
}
  1. lock_guard 与 unique_lock 的区别

    image-20251016202212803

默认成员初始化器

  1. 什么是默认成员初始化器

    ​ 在类或结构体中,直接在成员变量声明时用 = value{value} 的方式给它一个初始值。

    class MyClass {
    private:
        int mValue = 42;                              // ✅ 默认成员初始化器
        std::string mName{"Unknown"};                 // ✅ 默认成员初始化器
        std::unique_ptr<Logger> mLogger = std::make_unique<Logger>(); // ✅
    
    public:
        MyClass() = default;          // 构造函数没有显式初始化成员
        MyClass(int v) : mValue(v) {} // 但也可以在构造函数中覆盖
    };
    
  2. 他解决什么问题

    在 C++11 之前,你必须在 每个构造函数的初始化列表中 显式初始化成员:

    // C++03 风格(麻烦!)
    class MyClass {
        int mValue;
        std::string mName;
        Logger* mLogger;
    
    public:
        MyClass() : mValue(42), mName("Unknown"), mLogger(new Logger()) {}
        MyClass(int v) : mValue(v), mName("Unknown"), mLogger(new Logger()) {}
        // 如果有更多构造函数,都要重复写一遍!
    };
    
    • 代码重复

    • 容易出错(忘记初始化某个成员)

    • 维护困难

      使用默认成员初始化器后:

    class MyClass {
        int mValue = 42;
        std::string mName{"Unknown"};
        std::unique_ptr<Logger> mLogger = std::make_unique<Logger>();
    
    public:
        MyClass() = default;     // 不用手动初始化了!
        MyClass(int v) : mValue(v) {} // 只覆盖需要改的
    };
    
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐