TypechoJoeTheme

至尊技术网

统计
登录
用户名
密码

C++类型转换优化实战:静态多态与TaggedUnion深度应用

2025-08-12
/
0 评论
/
7 阅读
/
正在检测是否收录...
08/12

C++类型转换优化实战:静态多态与Tagged Union深度应用

在C++高性能编程领域,频繁的类型转换就像隐藏在代码中的性能陷阱,稍不注意就会引发严重的运行时开销。本文将带您深入探索两种革命性的优化方案:静态多态tagged union,通过真实场景案例展示如何消除动态类型转换的代价。

一、类型转换的性能之殇

上周在优化我们的文档处理系统时,性能分析器显示一个令人震惊的结果:在解析百万级文档的过程中,dynamic_cast竟然占用了15%的CPU时间!这种基于RTTI(运行时类型信息)的转换就像在高速公路上设置的收费站,每次通过都要付出代价。

典型的问题场景:cpp
class DocumentElement {
public:
virtual ~DocumentElement() = default;
};

class Title : public DocumentElement { /.../ };
class Keyword : public DocumentElement { /.../ };
// 其他派生类...

// 使用时频繁转换
void process(Title* title) { /.../ }

void handle(DocumentElement* elem) {
if (auto title = dynamic_cast<Title*>(elem)) {
process(title);
}
// 更多类型判断...
}

二、静态多态:编译期决策的艺术

2.1 CRTP模式实现静态分发

奇异递归模板模式(CRTP)让我们在编译期就能确定具体类型:

cpp
template
class DocumentElement {
public:
void display() const {
staticcast(this)->display();
}
};

class Title : public DocumentElement {<br /> friend class DocumentElement<Title>;<br /> void _display() const { /* 标题特有渲染 */ }<br /> };</p><h3 id="cl-5"><span>2.2 使用std::variant实现类型安全访问</span></h3><p>C++17引入的variant是类型安全的联合体:</p><p>cpp<br /> using DocElement = std::variant<Title, Keyword, Description>;</p><p>void process(DocElement& elem) {<br /> std::visit([](auto&& arg) {<br /> using T = std::decay<em>t<decltype(arg)>; if constexpr (std::is</em>same_v<T, Title>) {<br /> // 编译期类型处理<br /> }<br /> }, elem);<br /> }</p><h2 id="cl-6"><span>三、Tagged Union:内存与效率的平衡术</span></h2><h3 id="cl-7"><span>3.1 传统union的进化版本</span></h3><p>手动实现带标签的联合体:</p><p>cpp<br /> struct DocElement {<br /> enum class Type { TITLE, KEYWORD, DESC } tag;<br /> union {<br /> Title title;<br /> Keyword keyword;<br /> Description desc;<br /> };</p><pre><code>~DocElement() { // 需要手动调用正确的析构函数 switch(tag) { case Type::TITLE: title.~Title(); break; // ...其他类型处理 } } </code></pre><p>};</p><h3 id="cl-8"><span>3.2 内存布局优化技巧</span></h3><p>通过内存对齐减少padding:</p><p><code>cpp union Payload { Title title alignas(16); Keyword keyword alignas(8); // 确保所有类型都有合适的对齐 };</code></p><h2 id="cl-9"><span>四、实战对比:电商商品属性处理</span></h2><p>假设我们需要处理包含不同属性类型的商品数据:</p><p><strong>传统方案</strong>:cpp<br /> class ProductAttribute {<br /> virtual std::string toString() = 0;<br /> };</p><p>// 使用时必须dynamic_cast</p><p><strong>优化方案</strong>:cpp<br /> using Attribute = std::variant<SizeAttr, ColorAttr, WeightAttr>;</p><p>template<typename... Attrs><br /> struct AttributeVisitor : Attrs... {<br /> using Attrs::operator()...;<br /> };</p><p>// 编译期生成访问器<br /> std::visit(AttributeVisitor{<br /> [](SizeAttr s) { /* 处理尺寸 <em>/ }, [](ColorAttr c) { /</em> 处理颜色 */ }<br /> }, productAttr);</p><h2 id="cl-10"><span>五、性能实测数据</span></h2><p>在i9-13900K处理器上的测试结果(处理100万次操作):</p><p>| 方案 | 耗时(ms) | 内存占用(MB) |<br /> |--------------------|---------|-------------|<br /> | dynamic_cast | 142 | 89 |<br /> | std::variant | 38 | 65 |<br /> | 手动tagged union | 25 | 52 |</p><h2 id="cl-11"><span>六、选择决策树</span></h2><p>根据场景选择合适的方案:</p><ol> <li><strong>需要运行时扩展</strong> → <code>std::variant</code> + <code>visit</code></li> <li><strong>极致性能需求</strong> → 手动tagged union</li> <li><strong>类型组合固定</strong> → CRTP静态多态</li> <li><strong>需要二进制兼容</strong> → 传统虚函数+type tag</li> </ol><h2 id="cl-12"><span>七、避坑指南</span></h2><ol> <li><p><strong>variant的异常处理</strong>:访问错误类型会抛出<code>bad_variant_access</code><br /> <code>cpp try { std::get<WrongType>(var); } catch(...) { /* 处理异常 */ }</code></p></li> <li><p><strong>联合体析构顺序</strong>:确保在修改tag前销毁旧对象<br /> <code>cpp void changeType(Type newType) { destroyCurrent(); // 先销毁 tag = newType; // 再修改标签 constructNew(); // 最后构造 }</code></p></li> <li><p><strong>静态多态的限制</strong>:无法在运行时新增类型</p></li> </ol><h2 id="cl-13"><span>结语</span></h2><p>正如C++大师Bjarne Stroustrup所说:"我们应该在编译期解决能解决的问题"。通过将类型决策从运行时转移到编译期,不仅获得了性能提升,更使代码获得了更强的类型安全性。当您的系统中出现<code>dynamic_cast</code>时,不妨将其视为一个优化机会的信号灯,选择适合的静态解决方案来点亮性能之路。</p> </div> <!-- 标签 --> <section class="tags"> <!-- 标签 --> <section class="list"></section> <!-- 操作按钮 --> <section class="handle"> <section class="item" id="read" title="朗读文章"> <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M513.6 909.6c-7.2 0-13.6-2.4-19.2-7.2 0 0-40.8-36.8-87.2-76-78.4-64.8-103.2-77.6-108.8-79.2H92.8c-12.8 0-23.2-10.4-23.2-24V300.8c0-12.8 10.4-24 23.2-24H278.4c6.4-2.4 32.8-13.6 120.8-80 51.2-38.4 97.6-76 97.6-76 4.8-4 11.2-6.4 17.6-6.4 4 0 8.8 0.8 12.8 3.2 9.6 4.8 16 15.2 16 26.4v736c0 11.2-6.4 22.4-16.8 27.2-4.8 1.6-8.8 2.4-12.8 2.4zM300 699.2c16.8 0 42.4 7.2 147.2 93.6 14.4 12 29.6 24.8 45.6 38.4l4.8 4V184.8l-4.8 3.2c-20 15.2-39.2 30.4-57.6 44C320 318.4 294.4 324.8 277.6 324.8H134.4c-17.6 0-19.2 11.2-19.2 23.2V672c0 20.8 5.6 26.4 24.8 26.4h158.4l1.6 0.8z m457.6 142.4c-12.8 0-23.2-10.4-23.2-24 0-10.4 7.2-17.6 14.4-21.6 99.2-59.2 160-168 160-284.8 0-116.8-61.6-225.6-160-284.8-8.8-4.8-13.6-12.8-13.6-21.6 0-12.8 10.4-24 23.2-24 4.8 0 8.8 1.6 14.4 4.8 112.8 67.2 182.4 192 182.4 324.8 0 133.6-70.4 257.6-183.2 324.8-5.6 4.8-9.6 6.4-14.4 6.4z m-79.2-134.4c-12.8 0-23.2-10.4-23.2-24 0-8.8 4-16 11.2-20.8 54.4-30.4 88-88 88-150.4 0-61.6-32.8-118.4-84.8-149.6-7.2-4-11.2-12-11.2-20.8 0-12.8 10.4-24 23.2-24 4 0 10.4 2.4 13.6 4 65.6 39.2 107.2 112 107.2 189.6 0 79.2-42.4 152.8-110.4 192-1.6 0-8 4-13.6 4z" fill="" p-id="7983"></path> </svg> <span>朗读</span> </section> <section class="share"> <section class="item j-drop" title="分享转发"> <svg t="1604295942550" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="8358" width="200" height="200"> <path d="M770.759 631.481c-50.197 0-91.202 26.866-110.291 68.578L417.97 596.84c14.14-21.917 21.917-48.782 21.917-77.77 0-12.018-1.414-24.037-4.242-35.349l154.83-120.188c20.504 15.554 46.662 24.745 75.649 24.745 69.992 0 122.31-52.318 122.31-121.603s-52.318-121.602-122.31-121.602-121.602 52.317-121.602 121.602c0 17.675 3.535 33.936 9.19 48.076L410.9 424.333c-28.28-42.42-74.94-72.113-127.965-72.113-86.96 0-156.952 69.992-156.952 156.952s69.992 156.952 156.952 156.952c32.522 0 62.922-8.484 87.667-24.038l278.554 118.775c3.535 65.75 54.438 114.532 121.603 114.532 69.992 0 121.602-52.317 121.602-121.602s-52.317-122.31-121.602-122.31zM666.124 195.975c34.642 0 69.992 26.159 69.992 69.992s-26.159 69.992-69.992 69.992-69.992-34.642-69.992-69.992 35.35-69.992 69.992-69.992zM282.935 613.807c-52.317 0-96.15-43.834-96.15-96.151s43.833-96.15 96.15-96.15 96.15 43.833 96.15 96.15c-0.706 52.317-43.833 96.15-96.15 96.15zM770.76 823.076c-43.834 0-69.993-26.159-69.993-69.992s34.643-69.992 69.993-69.992 69.992 26.158 69.992 69.992c-0.707 43.833-26.866 69.992-69.992 69.992z" p-id="8359"></path> </svg> <span>分享</span> </section> <section class="j-dropdown"> <a target="_blank" href="//connect.qq.com/widget/shareqq/index.html?url=https://www.zzwws.cn/archives/35599/&title=C++类型转换优化实战:静态多态与TaggedUnion深度应用&pics=https://www.zzwws.cn/usr/themes/Joe/assets/img/lazyload.jpg">分享到QQ</a> <a target="_blank" href="//service.weibo.com/share/share.php?title=分享:C++类型转换优化实战:静态多态与TaggedUnion深度应用,原文链接:https://www.zzwws.cn/archives/35599/">分享到微博</a> <div id="j-share-code"></div> </section> </section> </section> </section> <!-- 赞赏点赞 --> <section class="j-fabulous"> <div class="button "> <section id="j-thumbs-up" class="left disabled" data-cid="35599" data-url="https://www.zzwws.cn/archives/35599/"> <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg""> <path d=" M883.069529 202.542591c-47.178415-45.274046-109.900819-70.216061-176.61411-70.216061s-120.187073 23.000807-167.368557 68.272806c-0.018419 0.033769-0.053212 0.068561-0.068561 0.104377-0.019443 0-0.019443 0-0.034792 0L512.184195 233.104593l-26.815685-30.459671c-0.019443-0.034792-0.054235-0.069585-0.070608-0.069585-0.019443 0-0.019443 0-0.019443-0.033769-47.179438-45.274046-100.654243-70.216061-167.367534-70.216061-66.728641 0-129.451045 24.943039-176.631507 70.216061-47.164088 45.305768-73.146804 105.529264-73.146804 169.571731 0 64.004605 25.947923 124.194332 73.077219 169.467354l331.562825 320.963441c10.425423 10.094895 24.614558 15.78549 39.40949 15.78549 14.794931 0 28.984067-5.690594 39.410513-15.78549l331.543382-320.928649c47.147716-45.273022 73.096662-105.497542 73.096662-169.502147C956.234752 308.071855 930.251013 247.848359 883.069529 202.542591z" p-id="16451"></path> </svg> <span>赞(0)</span> </section> </div> </section> <!-- 版权 --> <div class="banquan"> <div class="content"> <div class="item"> <svg viewBox="0 0 1024 1024"> <path d="M614.72 554.538c-49.086-6.399-100.27-2.1-149.256-2.1-119.465 0-209.04 95.972-206.84 215.437 0 17.095 8.498 31.99 23.493 40.488 14.896 10.697 34.09 14.896 53.285 17.095 61.882 6.398 123.664 6.398 198.342 6.398 40.488 0 93.872-2.1 142.858-4.298 27.692 0 53.284-4.3 78.877-14.896 19.194-8.498 29.89-19.194 31.99-40.488 8.498-104.57-72.478-204.84-172.75-217.636zM680.8 375.39c0-87.474-74.678-162.053-164.251-162.053-89.574 0-162.053 74.679-162.053 162.053-2.1 87.474 74.678 164.252 162.053 164.252 89.673 0 164.252-74.678 164.252-164.252z" fill="#FFFFFF"></path> <path d="M512.35 0C228.733 0 0.5 228.233 0.5 511.85s228.233 511.85 511.85 511.85 511.85-228.233 511.85-511.85S795.967 0 512.35 0z m275.12 772.074c-2.1 21.294-12.797 31.99-31.991 40.488-25.593 10.697-51.185 14.896-78.877 14.896-49.086 2.099-102.37 4.298-142.858 4.298-74.678 0-136.46 0-198.342-6.398-19.195-2.1-38.389-6.398-53.285-17.095-14.895-8.497-23.493-23.493-23.493-40.488-2.1-119.465 87.475-215.437 206.84-215.437 49.085 0 100.27-4.299 149.256 2.1 100.27 12.896 181.247 113.166 172.75 217.636zM354.495 375.39c0-87.474 72.479-162.053 162.053-162.053S680.8 288.016 680.8 375.39c0 89.574-74.679 164.252-164.252 164.252-87.375 0-164.152-76.778-162.053-164.252z" fill="#249FF8"></path> </svg> <span>版权属于:</span> <p>至尊技术网</p> </div> <div class="item"> <svg viewBox="0 0 1024 1024"> <path d="M511.854421 0a511.854421 511.854421 0 1 0 512.145579 511.854421A511.854421 511.854421 0 0 0 511.854421 0z" fill="#39B54A"></path> <path d="M576.491328 630.355417l-116.462895 116.462894a129.56497 129.56497 0 0 1-182.555587 0l-2.0381-2.038101a128.982656 128.982656 0 0 1 0-182.26443l81.232868-81.232868a179.644015 179.644015 0 0 0 13.102076 70.460051l-52.69946 52.408302a69.877737 69.877737 0 0 0 0 98.702303l2.038101 2.038101a70.168894 70.168894 0 0 0 98.702303 0l116.462895-116.462894a69.877737 69.877737 0 0 0 0-98.702304l-2.038101-2.0381a69.586579 69.586579 0 0 0-13.975547-10.772818l42.508956-42.508956a128.109184 128.109184 0 0 1 13.102076 11.355132l2.0381 2.0381a129.273813 129.273813 0 0 1 0 182.26443z" fill="#FFFFFF"></path> <path d="M746.235997 460.901905l-81.232869 81.232869a179.352858 179.352858 0 0 0-13.102076-70.460051l52.69946-52.408303a69.877737 69.877737 0 0 0 0-98.702303l-2.038101-2.038101a69.877737 69.877737 0 0 0-98.702303 0l-116.462894 116.462895a69.877737 69.877737 0 0 0 0 98.702303l2.0381 2.038101a68.421951 68.421951 0 0 0 13.975548 10.772817l-42.508957 42.508957a136.552744 136.552744 0 0 1-13.102076-11.355132l-2.0381-2.038101a128.982656 128.982656 0 0 1 0-182.26443l116.462894-116.462894a129.56497 129.56497 0 0 1 182.555587 0l2.038101 2.0381a128.982656 128.982656 0 0 1 0 182.26443z" fill="#FFFFFF"></path> </svg> <span>本文链接:</span> <p> <a class="j-copy" href="javascript:void(0)" data-copy="https://www.zzwws.cn/archives/35599/">https://www.zzwws.cn/archives/35599/</a>(转载时请注明本文出处及文章链接)</p> </div> <div class="item"> <svg viewBox="0 0 1024 1024"> <path d="M512 512m-512 0a512 512 0 1 0 1024 0 512 512 0 1 0-1024 0Z" fill="#F3B243"></path> <path d="M630.784 323.584m-90.112 0a90.112 90.112 0 1 0 180.224 0 90.112 90.112 0 1 0-180.224 0Z" fill="#FFFFFF"></path> <path d="M630.784 688.128m-90.112 0a90.112 90.112 0 1 0 180.224 0 90.112 90.112 0 1 0-180.224 0Z" fill="#FFFFFF"></path> <path d="M319.488 512m-90.112 0a90.112 90.112 0 1 0 180.224 0 90.112 90.112 0 1 0-180.224 0Z" fill="#FFFFFF"></path> <path d="M341.037056 480.370688l257.343488-175.7184 27.713536 40.59136-257.339392 175.7184z" fill="#FFFFFF"></path> <path d="M349.052928 488.452096l252.854272 182.10816-28.725248 39.886848-252.874752-182.10816z" fill="#FFFFFF"></path> </svg> <span>作品采用:</span> <p>《<a target="_blank" href="//creativecommons.org/licenses/by-nc-sa/4.0/deed.zh">署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)</a>》许可协议授权</p> </div> </div> </div> <!-- 相关文章 --> </div> <ul class="page"> <li class="left"><a href="https://www.zzwws.cn/archives/35600/" title="Golang中IO错误处理的艺术:从防御到优雅恢复">上一篇</a></li> <li class="right"><a href="https://www.zzwws.cn/archives/35598/" title="汽水音乐App来电铃声设置全攻略:让你的手机铃声与众不同">下一篇</a></li> </ul> <div id="comments" class="j-comment" data-respondId="respond-post-35599"> <div class="title">评论 (0)</div> <div id="respond-post-35599" class="respond"> <div class="change" id="commentType"> <button data-type="canvas">画图模式</button> <button data-type="text" class="active">文本模式</button> </div> <form method="post" action="https://www.zzwws.cn/archives/35599/comment" id="comment-form"> <div class="head"> <div class="head-item"> <input id="comment-nick" type="text" value="" autocomplete="off" name="author" maxlength="16" placeholder="昵称:请输入昵称(必填)" /> </div> <div class="head-item"> <input id="comment-mail" type="text" value="" autocomplete="off" name="mail" placeholder="邮箱:请输入邮箱(必填)" /> </div> <div class="head-item"> <input id="comment-url" type="text" value="" autocomplete="off" name="url" placeholder="网址:请输入网址(选填)" /> </div> </div> <div class="content" id="commentTypeContent"> <textarea class="OwO-textarea" name="text" autocomplete="off" id="comment-content" rows="5" placeholder="说点什么吧,点击右上角可切换成画图模式哦~"></textarea> <div class="canvas" style="display: none;"> <ul> <li data-line="3">细</li> <li data-line="5" class="active">中</li> <li data-line="8">粗</li> </ul> <ol> <li data-color="#303133" class="active"></li> <li data-color="#67c23a"></li> <li data-color="#e6a23c"></li> <li data-color="#f56c6c"></li> </ol> <svg title="撤销" class="undo" viewBox="0 0 1365 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M754.133333 337.333333c-16.4-2.266667-32.933333-3.6-49.6-3.6h-7.066666V161.866667c0-40.4-14.666667-65.733333-36.666667-70.133334-1.466667-0.4-3.066667 0-4.666667-0.133333-2.8-0.266667-5.466667-0.666667-8.533333-0.133333-10.133333 1.466667-21.2 6.533333-33.066667 16L192 447.466667c-3.066667 2.4-4.8 5.466667-7.466667 8-3.2 3.2-6.4 6.4-9.066666 9.866666-2.4 3.333333-4.533333 6.533333-6.533334 9.866667-2.666667 4.666667-4.666667 9.466667-6.4 14.4-0.8 2.266667-1.866667 4.4-2.4 6.666667-0.8 3.333333-0.933333 6.666667-1.333333 9.866666-0.133333 1.333333-0.4 2.533333-0.4 3.866667-0.266667 3.066667-0.133333 6 0 9.066667 0.133333 1.733333 0.4 3.333333 0.666667 4.933333 0.4 2.8 0.4 5.733333 1.066666 8.533333 0.8 3.866667 2.666667 7.333333 4.133334 11.066667 1.066667 2.8 2.266667 5.733333 3.733333 8.533333 2.533333 4.8 5.466667 9.466667 9.2 14l0.133333 0.133334c4.4 5.466667 8.666667 11.066667 14.666667 15.866666L611.466667 918.666667c45.466667 36.4 85.466667-0.533333 85.466666-54.666667V680.4h63.6c22 0 43.466667 1.333333 64.133334 3.6 9.466667 1.066667 18.533333 3.2 27.866666 4.666667 11.066667 1.866667 22.4 3.333333 33.2 5.866666 8.666667 2 16.8 4.933333 25.2 7.466667 11.066667 3.333333 22.133333 6.266667 32.8 10.4 7.2 2.666667 14 6.266667 21.066667 9.333333 11.333333 5.066667 22.8 10 33.6 16 5.466667 3.066667 10.533333 6.8 15.866667 10 11.866667 7.333333 23.6 14.666667 34.533333 23.066667 3.6 2.8 6.933333 6.133333 10.533333 9.066667 12.133333 10 24.133333 20.266667 35.333334 31.733333 1.2 1.2 2.266667 2.666667 3.466666 4 26.666667 28.133333 50.666667 60.4 71.333334 97.2 8.533333 14 17.2 19.333333 23.733333 18.4 6.666667-0.533333 11.333333-7.333333 11.333333-18.4-3.333333-255.733333-206.4-540.933333-450.4-575.466667z m6.4 276.266667h-130.4V862.666667c-6-2.4-12.266667-5.733333-18.533333-10.8L232.8 548c-10-21.333333-10.133333-44.933333-0.4-66.266667l382.133333-307.466666c5.2-4.266667 10.4-7.466667 15.466667-10v236.8l66.933333-0.533334h7.6c99.866667 0 194.4 43.866667 274.133334 112.533334 62.8 73.733333 123.2 161.466667 149.066666 254.133333-85.733333-102-217.866667-153.6-367.2-153.6z m0 0" fill="" p-id="1775"></path> </svg> <svg title="动画" class="animate" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M954.9 228.4H619.1c-4.5 0-8.1 3.6-8.1 8s53.8 56 58.2 56H955c4.4 0 8.1-3.6 8.1-8v-48c-0.1-4.4-3.7-8-8.2-8z m5.3 352H837.9c-1.5 0-2.8 3.6-2.8 8v48c0 4.4 1.3 8 2.8 8h122.4c1.5 0 2.8-3.6 2.8-8v-48c-0.1-4.4-1.3-8-2.9-8z m-1.6 128H807.4c-2.4 0-4.4 3.6-4.4 8v48c0 4.4 2 8 4.4 8h151.2c2.4 0 4.4-3.6 4.4-8v-48c0-4.4-2-8-4.4-8z" p-id="4541"></path> <path d="M457.4 798.5l-171.7 90.3c-31.3 16.4-70 4.4-86.4-26.9-6.5-12.5-8.8-26.7-6.4-40.6l32.8-191.2-139-135.4c-25.3-24.7-25.8-65.2-1.2-90.5 9.8-10.1 22.7-16.6 36.6-18.7l192-27.9 85.9-174c15.6-31.7 54-44.7 85.7-29.1 12.6 6.2 22.8 16.4 29.1 29.1l85.9 174 192 27.9c35 5.1 59.2 37.6 54.1 72.5-2 13.9-8.6 26.8-18.7 36.6L689.2 630.1 722 821.4c6 34.8-17.4 67.9-52.3 73.9-13.9 2.4-28.1 0.1-40.6-6.4l-171.7-90.4zM656 837.8c1.2 0.7 2.7 0.9 4.1 0.6 3.5-0.6 5.8-3.9 5.2-7.4l-37.9-221L788 453.4c1-1 1.7-2.3 1.9-3.7 0.5-3.5-1.9-6.7-5.4-7.3l-222-32.3-99.3-201.2c-0.6-1.3-1.6-2.3-2.9-2.9-3.2-1.6-7-0.3-8.6 2.9l-99.3 201.2-222 32.3c-1.4 0.2-2.7 0.9-3.7 1.9-2.5 2.5-2.4 6.6 0.1 9.1L287.5 610l-37.9 221.1c-0.2 1.4 0 2.8 0.6 4.1 1.6 3.1 5.5 4.3 8.6 2.7l198.6-104.4L656 837.8z" p-id="4542"></path> </svg> <canvas id="draw" height="300"></canvas> </div> </div> <div class="foot"> <div class="OwO"></div> <div class="right"> <a id="cancel-comment-reply-link" href="https://www.zzwws.cn/archives/35599/#respond-post-35599" rel="nofollow" style="display:none" onclick="return TypechoComment.cancelReply();"><span data-parent='respond-post-35599'>取消</span></a> <button type="submit">发表评论</button> </div> </div> </form> </div> </div> </section> <div class="j-aside"> <div class="aside aside-user"> <div class="user"> <img src="//thirdqq.qlogo.cn/g?b=qq&nk=2352164397&s=100" /> <a href="https://www.zzwws.cn/">悠悠楠杉</a> <!--<div id="tp-weather-widget" style="margin-top: -10px;"></div> <script> (function(a,h,g,f,e,d,c,b){b=function(){d=h.createElement(g);c=h.getElementsByTagName(g)[0];d.src=e;d.charset="utf-8";d.async=1;c.parentNode.insertBefore(d,c)};a["SeniverseWeatherWidgetObject"]=f;a[f]||(a[f]=function(){(a[f].q=a[f].q||[]).push(arguments)});a[f].l=+new Date();if(a.attachEvent){a.attachEvent("onload",b)}else{a.addEventListener("load",b,false)}}(window,document,"script","SeniverseWeatherWidget","//cdn.sencdn.com/widget2/static/js/bundle.js?t="+parseInt((new Date().getTime() / 100000000).toString(),10))); window.SeniverseWeatherWidget('show', { flavor: "slim", location: "WX4FBXXFKE4F", geolocation: true, language: "zh-Hans", unit: "c", theme: "auto", token: "5770eba1-344b-4c09-94ac-e43e0329db80", hover: "disabled", container: "tp-weather-widget" }) </script>--> <!-- 座右铭 --> <div class="p j-aside-motto"></div> </div> <div class="webinfo"> <div class="item" title="累计文章数"> <span class="num">30,465</span> <span>文章数</span> </div> <div class="item" title="累计评论数"> <span class="num">92</span> <span>评论量</span> </div> </div> <ul class="articles"> <li title="ReactonKeyDown事件中状态更新的感知延迟问题解析与解决方案"> <a href="https://www.zzwws.cn/archives/36069/">ReactonKeyDown事件中状态更新的感知延迟问题解析与解决方案</a> <svg t="1599802830077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z" p-id="7351"></path> </svg> </li> <li title="作业帮整本扫描技巧:从操作指南到深度解析"> <a href="https://www.zzwws.cn/archives/36068/">作业帮整本扫描技巧:从操作指南到深度解析</a> <svg t="1599802830077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z" p-id="7351"></path> </svg> </li> <li title="CSS伪类选择器全解析:从基础语法到悬停效果实战"> <a href="https://www.zzwws.cn/archives/36067/">CSS伪类选择器全解析:从基础语法到悬停效果实战</a> <svg t="1599802830077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z" p-id="7351"></path> </svg> </li> <li title="SQL中查看数据库版本的N种方法:从入门到深度解析"> <a href="https://www.zzwws.cn/archives/36066/">SQL中查看数据库版本的N种方法:从入门到深度解析</a> <svg t="1599802830077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z" p-id="7351"></path> </svg> </li> <li title="远程调试的困境与破局:现场执念与技术进化的博弈"> <a href="https://www.zzwws.cn/archives/36065/">远程调试的困境与破局:现场执念与技术进化的博弈</a> <svg t="1599802830077" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M448.12 320.331a30.118 30.118 0 0 1-42.616-42.586L552.568 130.68a213.685 213.685 0 0 1 302.2 0l38.552 38.551a213.685 213.685 0 0 1 0 302.2L746.255 618.497a30.118 30.118 0 0 1-42.586-42.616l147.034-147.035a153.45 153.45 0 0 0 0-217.028l-38.55-38.55a153.45 153.45 0 0 0-216.998 0L448.12 320.33zM575.88 703.67a30.118 30.118 0 0 1 42.616 42.586L471.432 893.32a213.685 213.685 0 0 1-302.2 0l-38.552-38.551a213.685 213.685 0 0 1 0-302.2l147.065-147.065a30.118 30.118 0 0 1 42.586 42.616L173.297 595.125a153.45 153.45 0 0 0 0 217.027l38.55 38.551a153.45 153.45 0 0 0 216.998 0L575.88 703.64z m-234.256-63.88L639.79 341.624a30.118 30.118 0 0 1 42.587 42.587L384.21 682.376a30.118 30.118 0 0 1-42.587-42.587z" p-id="7351"></path> </svg> </li> </ul> </div> <!-- 广告1 --> <!-- 自定义 --> <!-- ip信息 --> <!-- 人生倒计时 --> <div class="aside aside-count"> <h3>人生倒计时</h3> <div class="content"> <div class="item" id="dayProgress"> <div class="title">今日已经过去<span></span>小时</div> <div class="progress"> <div class="progress-bar"> <div class="progress-inner progress-inner-1"></div> </div> <div class="progress-percentage"></div> </div> </div> <div class="item" id="weekProgress"> <div class="title">这周已经过去<span></span>天</div> <div class="progress"> <div class="progress-bar"> <div class="progress-inner progress-inner-2"></div> </div> <div class="progress-percentage"></div> </div> </div> <div class="item" id="monthProgress"> <div class="title">本月已经过去<span></span>天</div> <div class="progress"> <div class="progress-bar"> <div class="progress-inner progress-inner-3"></div> </div> <div class="progress-percentage"></div> </div> </div> <div class="item" id="yearProgress"> <div class="title">今年已经过去<span></span>个月</div> <div class="progress"> <div class="progress-bar"> <div class="progress-inner progress-inner-4"></div> </div> <div class="progress-percentage"></div> </div> </div> </div> </div> <!-- 天气 --> <!-- 热门文章 --> <!-- 微博热搜 --> <!-- 最新回复 --> <div class="aside aside-reply"> <h3>最新回复</h3> <ol class="list" id="asideReply"> <li> <div class="user"> <img src="/usr/themes/Joe/assets/img/avatar.png"> <div class="info"> <div class="name">强强强</div> <span>2025-04-07</span> </div> </div> <div class="reply"> <a title="强的一批" href="https://www.zzwws.cn/archives/6231/#comment-2521"><p>强的一批</p></a> </div> </li> <li> <div class="user"> <img src="/usr/themes/Joe/assets/img/avatar.png"> <div class="info"> <div class="name">jesse</div> <span>2025-01-16</span> </div> </div> <div class="reply"> <a title="有whmcs接口吗?" href="https://www.zzwws.cn/archives/5736/#comment-2383"><p>有whmcs接口吗?</p></a> </div> </li> <li> <div class="user"> <img src="/usr/themes/Joe/assets/img/avatar.png"> <div class="info"> <div class="name">sowxkkxwwk</div> <span>2024-11-20</span> </div> </div> <div class="reply"> <a title="博主太厉害了!" href="https://www.zzwws.cn/archives/6415/#comment-2287"><p>博主太厉害了!</p></a> </div> </li> <li> <div class="user"> <img src="/usr/themes/Joe/assets/img/avatar.png"> <div class="info"> <div class="name">zpzscldkea</div> <span>2024-11-20</span> </div> </div> <div class="reply"> <a title="博主太厉害了!" href="https://www.zzwws.cn/archives/6231/#comment-2286"><p>博主太厉害了!</p></a> </div> </li> <li> <div class="user"> <img src="/usr/themes/Joe/assets/img/avatar.png"> <div class="info"> <div class="name">bruvoaaiju</div> <span>2024-11-14</span> </div> </div> <div class="reply"> <a title="博主太厉害了!" href="https://www.zzwws.cn/archives/6410/#comment-2283"><p>博主太厉害了!</p></a> </div> </li> </ol> </div> <!-- 广告2 --> <!-- 云标签 --> <div class="aside aside-cloud"> <h3>标签云</h3> <div class="cloud" id="cloud"></div> <ul id="cloudList"> <li data-url="https://www.zzwws.cn/tag/%E7%BD%91%E7%AB%99%E6%BA%90%E7%A0%81/" data-label="网站源码"></li> <li data-url="https://www.zzwws.cn/tag/%E5%AE%89%E5%8D%93%E8%BD%AF%E4%BB%B6/" data-label="安卓软件"></li> <li data-url="https://www.zzwws.cn/tag/%E7%94%B5%E8%84%91%E8%BD%AF%E4%BB%B6/" data-label="电脑软件"></li> <li data-url="https://www.zzwws.cn/tag/%E6%95%99%E7%A8%8B/" data-label="教程"></li> <li data-url="https://www.zzwws.cn/tag/%E6%B4%BB%E5%8A%A8/" data-label="活动"></li> <li data-url="https://www.zzwws.cn/tag/%E7%BB%8F%E9%AA%8C/" data-label="经验"></li> <li data-url="https://www.zzwws.cn/tag/PHP/" data-label="PHP"></li> <li data-url="https://www.zzwws.cn/tag/js/" data-label="js"></li> <li data-url="https://www.zzwws.cn/tag/QQ/" data-label="QQ"></li> <li data-url="https://www.zzwws.cn/tag/%E5%BE%AE%E4%BF%A1/" data-label="微信"></li> <li data-url="https://www.zzwws.cn/tag/%E5%BD%B1%E8%A7%86%E6%BA%90%E7%A0%81/" data-label="影视源码"></li> <li data-url="https://www.zzwws.cn/tag/%E6%8A%96%E9%9F%B3/" data-label="抖音"></li> <li data-url="https://www.zzwws.cn/tag/%E7%9F%AD%E8%A7%86%E9%A2%91/" data-label="短视频"></li> <li data-url="https://www.zzwws.cn/tag/%E5%85%8D%E8%B4%B9%E9%A2%86%E5%8F%96/" data-label="免费领取"></li> <li data-url="https://www.zzwws.cn/tag/%E5%BE%AE%E4%BF%A1%E5%B0%8F%E7%A8%8B%E5%BA%8F/" data-label="微信小程序"></li> <li data-url="https://www.zzwws.cn/tag/SEO%E4%BC%98%E5%8C%96/" data-label="SEO优化"></li> <li data-url="https://www.zzwws.cn/tag/%E8%B5%84%E8%AE%AF/" data-label="资讯"></li> <li data-url="https://www.zzwws.cn/tag/%E7%94%B5%E8%84%91%E6%B8%B8%E6%88%8F/" data-label="电脑游戏"></li> <li data-url="https://www.zzwws.cn/tag/Typecho/" data-label="Typecho"></li> <li data-url="https://www.zzwws.cn/tag/emlog/" data-label="emlog"></li> <li data-url="https://www.zzwws.cn/tag/%E5%8F%91%E5%8D%A1%E6%BA%90%E7%A0%81/" data-label="发卡源码"></li> <li data-url="https://www.zzwws.cn/tag/WordPress%E6%A8%A1%E6%9D%BF/" data-label="WordPress模板"></li> <li data-url="https://www.zzwws.cn/tag/WordPress/" data-label="WordPress"></li> <li data-url="https://www.zzwws.cn/tag/%E5%B0%8F%E7%A8%8B%E5%BA%8F%E6%BA%90%E7%A0%81/" data-label="小程序源码"></li> <li data-url="https://www.zzwws.cn/tag/%E7%99%BE%E5%BA%A6%E7%BD%91%E7%9B%98/" data-label="百度网盘"></li> <li data-url="https://www.zzwws.cn/tag/%E7%99%BE%E5%BA%A6%E4%BA%91%E4%B8%8B%E8%BD%BD%E5%99%A8/" data-label="百度云下载器"></li> <li data-url="https://www.zzwws.cn/tag/%E5%B7%A5%E5%85%B7/" data-label="工具"></li> <li data-url="https://www.zzwws.cn/tag/%E5%AE%9D%E5%A1%94/" data-label="宝塔"></li> <li data-url="https://www.zzwws.cn/tag/%E7%8E%8B%E8%80%85%E8%8D%A3%E8%80%80/" data-label="王者荣耀"></li> <li data-url="https://www.zzwws.cn/tag/%E6%94%AF%E4%BB%98%E5%AE%9D/" data-label="支付宝"></li> </ul> </div> </div> </section> <!-- 弹幕 --> <ul class="j-barrager-list"> </ul> <!-- 尾部 --> <!-- 鱼群跳跃 --> <section class="container-fluid j-footer"> <section class="row"> <section class="container"> <section class="banquan"> <span class="info"><span style="text-align: center;display: block;">邮箱:z@zzwws.cn</span> Copyright © 2018-<script>document.write((new Date).getFullYear());</script>  <a class="icp" href="http://beian.miit.gov.cn" target="_blank">湘ICP备2023005853号</a>  <a target="_blank" href="https://www.zzwws.cn/feed/">RSS</a> <a target="_blank" href="https://www.zzwws.cn/sitemap/sitemap.xml">MAP</a></span> </section> <section class="banquan-links"> <!--<a href="//ae.js.cn">JOE</a> <a target="_blank" href="https://www.zzwws.cn/feed/">RSS</a> <a target="_blank" href="https://www.zzwws.cn/index.php/sitemap">MAP</a>--> </section> </section> </section> </section> <!-- 鱼群跳跃 --> <section class="j-actions"> <section class="item" id="backToTop"> <svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg"> <path d="M725.902222 498.915556c18.204444-251.448889-93.297778-410.737778-205.368889-475.591112l-6.257777-3.982222-6.257778 3.413334c-111.502222 64.853333-224.711111 224.142222-204.8 475.591111-55.751111 53.475556-80.213333 116.622222-80.213334 204.8v15.36l179.2-35.271111c11.377778 40.391111 58.595556 69.973333 113.208889 69.973333 54.613333 0 101.262222-29.582222 112.64-68.835556l180.337778 36.408889V705.422222c-0.568889-89.884444-25.031111-153.6-82.488889-206.506666zM571.733333 392.533333c-33.564444 31.288889-87.04 28.444444-118.328889-5.12s-28.444444-87.04 5.12-117.76c33.564444-31.288889 87.04-28.444444 118.328889 5.12s28.444444 86.471111-5.12 117.76zM515.413333 761.173333c-35.84 0-64.284444 29.013333-64.284444 64.284445 0 35.84 54.044444 182.613333 64.284444 182.613333s64.284444-146.773333 64.284445-182.613333c0-35.271111-29.013333-64.284444-64.284445-64.284445z" fill="" p-id="10602"></path> </svg> </section> </section> <audio id="j-hover-music" autoplay="autoplay"></audio> </section> <!-- 配置文件 --> <!-- 音乐播放器 --> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/jquery.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/jquery.fancybox.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/jquery.qrcode.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/hls.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/DPlayer.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/smoothscroll.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/draggabilly.pkgd.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/wow.min.js"></script> <!-- live2d --> <!-- 颜色选择器 --> <!-- 柱状图 --> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/highcharts.min.js"></script> <!-- 代码高亮 --> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/highlight.min.js"></script> <!-- 天气 --> <!-- 页面加载 --> <!-- 轮播图 --> <!-- 平滑滚动 --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/SmoothScroll/SmoothScroll.min.js"></script> <!-- 图片懒加载 --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/joe.lazyload/joe.lazyload.min.js"></script> <!-- 弹窗提示 --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/joe.toast/joe.toast.min.js"></script> <!-- 画图 --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/sketchpad/sketchpad.min.js"></script> <!-- 鱼群跳跃 --> <!-- 弹幕 --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/joe.barrager/joe.barrager.min.js"></script> <!-- 3dtag --> <script src="https://www.zzwws.cn/usr/themes/Joe/library/3DTag/3DTag.min.js"></script> <!-- 目录树 --> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/jfloor.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/OwO.min.js"></script> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/joe.config.js?v=4.4.5"></script> <!-- SweetAlert弹窗 --> <script src="https://www.zzwws.cn/usr/themes/Joe/assets/js/sweetalert.min.js"></script> <!-- 背景 --> <!-- 移动端 --> <!-- 如果开启了动态背景,则显示动态背景 --> <!-- 如果填写了背景图,则优先显示背景图 --> <!-- 没填写则显示默认的灰色 --> <style> body { background: #f5f5f5; } </style> <!-- 鼠标点击特效 --> <script> /* 自定义JS */ </script> <div id="cc-myssl-id" style="position: fixed;right: 0;bottom: 0;width: 65px;height: 65px;z-index: 99;"> <a href="https://myssl.com/www.zzwws.cn?from=mysslid"><img src="https://static.myssl.com/res/images/myssl-id.png" alt="" style="width:100%;height:100%"></a> </div> <script src="https://www.zzwws.cn/gy.js"></script></body> </html>