@@ -345,7 +345,7 @@ <h2 id="index-_1">前言</h2>
345
345
<blockquote>
346
346
<p><img src="../img/bulb.png" height="30px" width="auto" style="margin: 0; border: none"/> 本书还在持续更新中……要追番的话,可以在 <a href="https://github.com/parallel101/cppguidebook">GitHub</a> 点一下右上角的 “Watch” 按钮,每当小彭老师提交新 commit,GitHub 会向你发送一峰电子邮件,提醒你小彭老师更新了。</p>
347
347
</blockquote>
348
- <p>更新时间:2024年08月04日 17:25:20 (UTC+08:00)</p>
348
+ <p>更新时间:2024年08月05日 12:24:25 (UTC+08:00)</p>
349
349
<h2 id="index-_2">格式约定</h2>
350
350
<blockquote>
351
351
<p><img src="../img/bulb.png" height="30px" width="auto" style="margin: 0; border: none"/> 用这种颜色字体书写的内容是温馨提示</p>
@@ -3569,8 +3569,10 @@ <h3 id="no_more_new-22">贴士 2.2</h3>
3569
3569
<pre><code class="language-cpp">auto foo = make_shared<Foo>();
3570
3570
</code></pre>
3571
3571
<blockquote>
3572
- <p>从 C++14 开始,内存安全的现代 C++ 程序中就不会出现任何显式的 new 了,哪怕是抱在 shared_ptr 或 unique_ptr 内的也不行。(除了最上面说的 3 种特殊情况) </p>
3572
+ <p><img src="../img/question.png" height="30px" width="auto" style="margin: 0; border: none"/> 有趣的是,make_shared 在 C++11 就引入了,make_unique 却直到 C++14 才引入。 </p>
3573
3573
</blockquote>
3574
+ <p>从 C++14 开始,内存安全的现代 C++ 程序中就不会出现任何显式的 new 了,哪怕是包在 shared_ptr 或 unique_ptr 内的也不行。(除了最上面说的 3 种特殊情况)</p>
3575
+ <h3 id="no_more_new-23">贴士 2.3</h3>
3574
3576
<p>如果你需要调用的 C 语言接口还需要原始指针的话,用 <code>.get()</code> 可以从智能指针中获取原始指针。建议只在和 C 语言打交道时 <code>.get()</code>,其余时间一律 shared_ptr 保证安全。</p>
3575
3577
<pre><code class="language-cpp">extern "C" void some_c_function(Foo *foo);
3576
3578
@@ -3711,7 +3713,27 @@ <h2 id="no_more_new-_5">线程安全?</h2>
3711
3713
<li>你会两个线程同时写入同一个原始指针吗?同样地,如果你原始指针不会犯错,shared_ptr 为什么会犯错?</li>
3712
3714
<li>你可以两个线程同时读取同一个全局的原始指针变量,同样地,shared_ptr 也可以,有任何区别吗?</li>
3713
3715
</ul>
3714
- <p>反正,shared_ptr 内部专门为线程安全做过设计,你不用去操心。</p></section><section class="print-page" id="stl_map"><h1 id="stl_map-stl-stdmap">STL 精讲:std::map 和他的朋友们</h1>
3716
+ <p>反正,shared_ptr 内部专门为线程安全做过设计,你不用去操心。</p>
3717
+ <h2 id="no_more_new-placement-new">placement new</h2>
3718
+ <p>placement new 和 placement delete 也可以用 std::construct_at 和 std::destroy_at 代替:</p>
3719
+ <pre><code class="language-cpp">#include <new>
3720
+
3721
+ struct Foo {
3722
+ explicit Foo(int age) { ... }
3723
+ Foo(Foo &&) = delete;
3724
+ ~Foo() { ... }
3725
+ };
3726
+
3727
+ void func() {
3728
+ alignas(Foo) unsigned char buffer[sizeof(Foo)];
3729
+ Foo *foo = std::construct_at(reinterpret_cast<Foo*>(buffer), 42, "hello"); // 等价于 new (buffer) Foo(42);
3730
+ ...
3731
+ std::destroy_at(foo); // 等价于 foo->~Foo();
3732
+ }
3733
+ </code></pre>
3734
+ <blockquote>
3735
+ <p><img src="../img/question.png" height="30px" width="auto" style="margin: 0; border: none"/> 在<a href="#cpp_memory">内存模型专题</a>中有进一步的详解。</p>
3736
+ </blockquote></section><section class="print-page" id="stl_map"><h1 id="stl_map-stl-stdmap">STL 精讲:std::map 和他的朋友们</h1>
3715
3737
<!-- PG1 -->
3716
3738
3717
3739
<p>让高性能数据结构惠及每一人</p>
0 commit comments