分享 Modern C++ 的冰山一角的一角
开源软件协会 RC
class Foo {
public:
    Foo(int num) : number_(num) {
    }
    int get_number() const {
        return number_;
    }
private:
    int number_ = 0;
};const float PI = 3.14;
// 除了默认访问说明符之外和 class 没有区别
struct Bar {
    float radius = 0.0;
    float length = 0.0;
    float get_volume() const {
        return PI * radius * radius * length;
    }
};void *p1 = 0; // bad!
void *p2 = NULL; // bad! same as (void *)0
void *p3 = nullptr; // good!Foo *foo = new Foo(2333);
int num = foo->get_number();
delete foo;
foo = nullptr; // avoid double free
int *arr = new int[233];
arr[232] = 1;
delete[] arr;using namespace foo::baz::foo;
using foo::bar::A;
using B = foo::bar::B;
using foo::get_the_answer;
struct D : A {
    using A::A;
};namespace foo {
    inline int get_the_answer() {
        return 42;
    }
    namespace bar {
        struct A {};
        class B {};
    } // namespace bar
    namespace baz::foo {
        enum class C { HELLO, WORLD };
    } // namespace baz::foo
} // namespace fooauto generate_map() {
    std::unordered_map<std::string, std::pair<int, std::tuple<float, float, float>>> map;
    map["foo"] = {1, {1.2, 1.3, 4.5}};
    return map;
}
void modify_map(decltype(generate_map()) &map) {
    map["bar"] = {2, {0.6, 7.8, 9.9}};
}
int main() {
    auto i = 42;
    auto b = true;
    auto vec = std::vector<int>{};
    auto map = generate_map();
    modify_map(map);
}struct Event {
    std::string type, user_id, message;
};
auto is_valid = [](const Event &event) -> bool {
    const static std::set<std::string> types{
        "message",
        "notice",
        "request",
    };
    return types.count(event.type) > 0;
};
auto e1 = Event{"message", "张三", "你好"};
auto e2 = Event{"foo", "小明", ""};
assert(is_valid(e1) && !is_valid(e2));auto gen_message_event = [] {
    return Event{"message", "", ""};
};
auto e = gen_message_event();
assert(e.type == "message");std::string s = "Hello, world!";
auto pos = std::find_if(
    s.cbegin(),
    s.cend(),
    [](auto ch) {
        return ch == ',' || ch == '!';
    }
);
assert(*pos == ',');std::string s = "Hello, world!";
auto pos = std::find_if(
    s.cbegin(),
    s.cend(),
    [](auto ch) {
        return ch == ',' || ch == '!';
    }
);
assert(*pos == ',');enum Direction { TOP = 0, RIGHT, BOTTOM, LEFT, INVALID };
auto direction = TOP;
auto next_direction = [&direction] {
    auto ret = direction;
    direction = static_cast<Direction>(direction + 1);
    if (direction == INVALID) direction = TOP;
    return ret;
};
for (int i = 0; i < 10; i++) {
    std::cout << next_direction() << std::endl;
}int read_n() {
    std::ifstream in("n.txt"); // 创建对象时,在构造函数中获取资源(打开文件)
    int n;
    in >> n;
    return n; // 离开作用域时,在析构函数中释放资源(关闭文件)
}std::mutex m;
void lock_bad() {
    m.lock();
    // do something
    m.unlock();
}
void lock_good() {
    std::lock_guard<std::mutex> lk(m);
    // do something
}std::mutex m;
void lock_good_2() {
    // do something
    {
        std::lock_guard<std::mutex> lk(m);
        // do something with lock
    }
    // do something
}struct Request {
    std::string method;
    std::string path;
    Headers headers;
    std::string body;
};
// 使用传统的 new、delete
auto request = new Request{.method = "POST", .path = "/", .body = "{}"};
// handle the request
delete request; // 如果忘记 delete,或 handle 时抛出异常,则内存泄漏
// 如果 Request 是 RAII 风格的类,遗漏 delete 将导致资源被占用,RAII 的优势瞬间丧失struct Request {
    std::string method;
    std::string path;
    Headers headers;
    std::string body;
};
// 使用 shared_ptr
auto request = std::shared_ptr<Request>(
    new Request{.method = "POST", .path = "/", .body = "{}"}
);
// handle the request
// 无需手动 delete,当引用计数降为 0 时会自动释放struct Response {
    Headers headers;
    std::string body;
};
auto response = std::make_shared<Response>(); // 完全避免使用 new{
    std::shared_ptr<int> p = nullptr;
    {
        auto tmp = std::make_shared<int>(42); // tmp 持有指针,引用计数为 1
        *tmp = 233;
        p = tmp; // 指针复制给 p,引用计数为 2
    } // 离开 tmp 的作用域,引用计数为 1
    assert(*p == 233);
} // 离开 p 的作用域,引用计数为 0,销毁对象、回收内存template <typename Elem>
class Vector {
public:
    Vector() : data_(nullptr), size_(0) {}
    Vector(size_t n) { data_ = new Elem[n], size_ = n; }
    ~Vector() { delete[] data_; }
    // ...
private:
    Elem *data_;
    size_t size_;
};
Vector<int> int_vec;
Vector<Vector<double>> double_vec_vec;template <typename T>
T sum(const std::vector<T> &vec) {
    T sum{}; // 零初始化
    for (const auto &item : vec) {
        sum += item; // T 需实现 += 运算
    }
    return sum;
}
auto s1 = sum<double>(std::vector<double>{1, 2.5});
auto s2 = sum(std::vector<int>{111, 222}); // 从参数可以推断出 T 时,无需显式指定