-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy patheffectiveCplusplus20210427.html
391 lines (283 loc) · 34.9 KB
/
effectiveCplusplus20210427.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
<!DOCTYPE html>
<html lang=en>
<head>
<!-- so meta -->
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="HandheldFriendly" content="True">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=5" />
<meta name="description" content="当你谨慎的设计出 classes (template) 和 function template 之后, 你依旧应该注意一些细节上的东西. 条款26: 太早的定义变量可能会导致效率上的拖延 条款27: 过度的使用转型,可能导致代码变慢,难以维护,以及难以理解的错误 条款28: 返回对象的内部数据的 handles ,可能会破坏封装,并留下 危险的handles 条款29: 未考虑异常则可能导致资源">
<meta property="og:type" content="article">
<meta property="og:title" content="Effective C++ 笔记三">
<meta property="og:url" content="https://tblgsn.github.io/effectiveCplusplus20210427.html">
<meta property="og:site_name" content="tblgsn的个人博客">
<meta property="og:description" content="当你谨慎的设计出 classes (template) 和 function template 之后, 你依旧应该注意一些细节上的东西. 条款26: 太早的定义变量可能会导致效率上的拖延 条款27: 过度的使用转型,可能导致代码变慢,难以维护,以及难以理解的错误 条款28: 返回对象的内部数据的 handles ,可能会破坏封装,并留下 危险的handles 条款29: 未考虑异常则可能导致资源">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2021-04-27T19:54:00.000Z">
<meta property="article:modified_time" content="2025-01-22T09:14:47.022Z">
<meta property="article:author" content="tblgsn">
<meta property="article:tag" content="C++">
<meta property="article:tag" content="effective C++">
<meta name="twitter:card" content="summary">
<link rel="shortcut icon" href="/images/favicon.ico">
<link rel="icon" type="image/png" href="/images/favicon-192x192.png" sizes="192x192">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png">
<!-- title -->
<title>Effective C++ 笔记三</title>
<!-- async scripts -->
<!-- Google Analytics -->
<!-- Umami Analytics -->
<!-- styles -->
<link rel="stylesheet" href="/css/style.css">
<!-- persian styles -->
<!-- rss -->
<link rel="alternate" href="/true" title="tblgsn的个人博客" type="application/atom+xml" />
<!-- mathjax -->
<script type="text/x-mathjax-config">
MathJax.Hub.Config({
tex2jax: {
skipTags: ['script', 'noscript', 'style', 'textarea', 'pre'],
inlineMath: [['$','$']]
}
});
</script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.5/latest.js?config=TeX-MML-AM_CHTML' async></script>
<meta name="generator" content="Hexo 7.0.0"></head>
<body class="max-width mx-auto px3 ltr">
<div id="header-post">
<a id="menu-icon" href="#" aria-label="Menu"><i class="fa-solid fa-bars fa-lg"></i></a>
<a id="menu-icon-tablet" href="#" aria-label="Menu"><i class="fa-solid fa-bars fa-lg"></i></a>
<a id="top-icon-tablet" href="#" aria-label="Top" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');" style="display:none;"><i class="fa-solid fa-chevron-up fa-lg"></i></a>
<span id="menu">
<span id="nav">
<ul>
<!--
--><li><a href="/">Home</a></li><!--
--><!--
--><li><a href="/archives/">Writing</a></li><!--
--><!--
--><li><a target="_blank" rel="noopener" href="http://github.com/tblgsn">Projects</a></li><!--
--><!--
--><li><a href="/about/">About</a></li><!--
-->
</ul>
</span>
<br/>
<span id="actions">
<ul>
<li><a class="icon" aria-label="Previous post" href="/effectiveCplusplus20210512.html"><i class="fa-solid fa-chevron-left" aria-hidden="true" onmouseover="$('#i-prev').toggle();" onmouseout="$('#i-prev').toggle();"></i></a></li>
<li><a class="icon" aria-label="Next post" href="/SGISTL20210423.html"><i class="fa-solid fa-chevron-right" aria-hidden="true" onmouseover="$('#i-next').toggle();" onmouseout="$('#i-next').toggle();"></i></a></li>
<li><a class="icon" aria-label="Back to top" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fa-solid fa-chevron-up" aria-hidden="true" onmouseover="$('#i-top').toggle();" onmouseout="$('#i-top').toggle();"></i></a></li>
<li><a class="icon" aria-label="Share post" href="#"><i class="fa-solid fa-share-alt" aria-hidden="true" onmouseover="$('#i-share').toggle();" onmouseout="$('#i-share').toggle();" onclick="$('#share').toggle();return false;"></i></a></li>
</ul>
<span id="i-prev" class="info" style="display:none;">Previous post</span>
<span id="i-next" class="info" style="display:none;">Next post</span>
<span id="i-top" class="info" style="display:none;">Back to top</span>
<span id="i-share" class="info" style="display:none;">Share post</span>
</span>
<br/>
<div id="share" style="display: none">
<ul>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://tblgsn.github.io/effectiveCplusplus20210427.html"><i class="fab fa-facebook " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&text=Effective C++ 笔记三"><i class="fab fa-twitter " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-linkedin " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&is_video=false&description=Effective C++ 笔记三"><i class="fab fa-pinterest " aria-hidden="true"></i></a></li>
<li><a class="icon" href="mailto:?subject=Effective C++ 笔记三&body=Check out this article: https://tblgsn.github.io/effectiveCplusplus20210427.html"><i class="fa-solid fa-envelope " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-get-pocket " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-reddit " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-stumbleupon " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-digg " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&name=Effective C++ 笔记三&description=<p>当你谨慎的设计出 classes (template) 和 function template 之后, 你依旧应该注意一些细节上的东西.</p>
<ul>
<li>条款26: 太早的定义变量可能会导致效率上的拖延</li>
<li>条款27: 过度的使用转型,可能导致代码变慢,难以维护,以及难以理解的错误</li>
<li>条款28: 返回对象的内部数据的 handles ,可能会破坏封装,并留下 危险的handles</li>
<li>条款29: 未考虑异常则可能导致资源的泄漏和数据的败坏</li>
<li>条款30: 过度的 使用inline 可能引起代码的膨胀</li>
<li>条款31: 过度的耦合则可能导致让人不满意的冗长建置时间(build times)"><i class="fab fa-tumblr " aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://tblgsn.github.io/effectiveCplusplus20210427.html&t=Effective C++ 笔记三"><i class="fab fa-hacker-news " aria-hidden="true"></i></a></li>
</ul>
</div>
<div id="toc">
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#26-%E5%B0%BD%E5%8F%AF%E8%83%BD%E7%9A%84%E5%BB%B6%E5%90%8E%E5%8F%98%E9%87%8F%E5%AE%9A%E4%B9%89%E5%BC%8F%E7%9A%84%E5%87%BA%E7%8E%B0%E6%97%B6%E9%97%B4"><span class="toc-number">1.</span> <span class="toc-text">26.尽可能的延后变量定义式的出现时间</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#27-%E5%B0%BD%E9%87%8F%E5%B0%91%E5%81%9A%E8%BD%AC%E5%9E%8B%E5%8A%A8%E4%BD%9C"><span class="toc-number">2.</span> <span class="toc-text">27.尽量少做转型动作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#28-%E9%81%BF%E5%85%8D%E8%BF%94%E5%9B%9E-handles-%E6%8C%87%E5%90%91%E5%AF%B9%E8%B1%A1%E5%86%85%E9%83%A8%E6%88%90%E5%88%86"><span class="toc-number">3.</span> <span class="toc-text">28. 避免返回 handles 指向对象内部成分</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#29-%E8%80%83%E8%99%91-%E2%80%9C%E5%87%BA%E7%8E%B0%E5%BC%82%E5%B8%B8%E2%80%9D%E7%9A%84%E6%83%85%E5%86%B5"><span class="toc-number">4.</span> <span class="toc-text">29. 考虑 “出现异常”的情况</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#30-inlining"><span class="toc-number">5.</span> <span class="toc-text">30. inlining</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#31-%E5%B0%86%E6%96%87%E4%BB%B6%E9%97%B4%E7%9A%84%E7%BC%96%E8%AF%91%E4%BE%9D%E5%AD%98%E5%85%B3%E7%B3%BB%E5%B0%86%E8%87%B3%E6%9C%80%E4%BD%8E"><span class="toc-number">6.</span> <span class="toc-text">31. 将文件间的编译依存关系将至最低</span></a></li></ol>
</div>
</span>
</div>
<div class="content index py4 ">
<article class="post h-entry" itemscope itemtype="http://schema.org/BlogPosting">
<header>
<h1 class="posttitle p-name" itemprop="name headline">
Effective C++ 笔记三
</h1>
<div class="meta">
<span class="author p-author h-card" itemprop="author" itemscope itemtype="http://schema.org/Person">
<span class="p-name" itemprop="name">@TBLGSn</span>
</span>
<div class="postdate">
<time datetime="2021-04-27T19:54:00.000Z" class="dt-published" itemprop="datePublished">2021-04-27</time>
</div>
<div class="article-tag">
<i class="fa-solid fa-tag"></i>
<a class="p-category" href="/tags/C/" rel="tag">C++</a>, <a class="p-category" href="/tags/effective-C/" rel="tag">effective C++</a>
</div>
</div>
</header>
<div class="content e-content" itemprop="articleBody">
<p>当你谨慎的设计出 classes (template) 和 function template 之后, 你依旧应该注意一些细节上的东西.</p>
<ul>
<li>条款26: 太早的定义变量可能会导致效率上的拖延</li>
<li>条款27: 过度的使用转型,可能导致代码变慢,难以维护,以及难以理解的错误</li>
<li>条款28: 返回对象的内部数据的 handles ,可能会破坏封装,并留下 危险的handles</li>
<li>条款29: 未考虑异常则可能导致资源的泄漏和数据的败坏</li>
<li>条款30: 过度的 使用inline 可能引起代码的膨胀</li>
<li>条款31: 过度的耦合则可能导致让人不满意的冗长建置时间(build times)<span id="more"></span></li>
</ul>
<h2 id="26-尽可能的延后变量定义式的出现时间"><a href="#26-尽可能的延后变量定义式的出现时间" class="headerlink" title="26.尽可能的延后变量定义式的出现时间"></a>26.尽可能的延后变量定义式的出现时间</h2><p>一旦你定义了一个变量,你就的为它付出代价.</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">encrytPassword</span><span class="params">(<span class="type">const</span> string& password)</span> </span>{</span><br><span class="line"> string encrypted;</span><br><span class="line"> <span class="keyword">if</span>(password.<span class="built_in">size</span>() == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> <span class="comment">//...</span></span><br><span class="line"> <span class="keyword">return</span> encrypted;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>传入的密码即使是空串,你依旧得付出 encrypted 的构造成本和析构成本,最好延后 encrypted 的定义式,直到确实需要它.</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">encrytPassword</span><span class="params">(<span class="type">const</span> string& password)</span> </span>{</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span>(password.<span class="built_in">size</span>() == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> string encrypted;</span><br><span class="line"> <span class="comment">//...</span></span><br><span class="line"> <span class="keyword">return</span> encrypted;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>现在,你需要付出 default 构造函数,进行赋值,析构的成本. 而条款4曾指出 “通过default 构造函数构造出一个对象然后对它赋值” 比 “直接在构造时指定初值” 效率差.<br>因此更好的代码是跳过无意义的 default 构造过程.</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="type">int</span> <span class="title">encrytPassword</span><span class="params">(<span class="type">const</span> string& password)</span> </span>{</span><br><span class="line"> </span><br><span class="line"> <span class="keyword">if</span>(password.<span class="built_in">size</span>() == <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">return</span> <span class="number">-1</span>;</span><br><span class="line"> <span class="function">string <span class="title">encrypted</span><span class="params">(password)</span></span>;</span><br><span class="line"> <span class="comment">//...</span></span><br><span class="line"> <span class="keyword">return</span> encrypted;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>“竟可能延后”的真正意思是: 你不只应该延后变量的定义,直到非得使用该变量的前一刻为止,你还应该延后这份定义直到能够给它初值实参为止.</p>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 方法A: 定义于循环外</span></span><br><span class="line">Widget w;</span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; +++i) {</span><br><span class="line"> w = ..;</span><br><span class="line">}</span><br><span class="line"><span class="comment">//方法B: 定义为循环内</span></span><br><span class="line"><span class="keyword">for</span>(<span class="type">int</span> i = <span class="number">0</span>; i < n; +++i) {</span><br><span class="line"> <span class="function">Widget <span class="title">w</span><span class="params">(...)</span></span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>我们现在来比较这两种方法:<br>方法A: 需要付出 1个构造函数 + 1个析构函数 + n 个 赋值操作<br>方法B: n个构造函数 + n 个 析构函数<br>如果 clases 的 一个赋值成本低于一个 构造+ 析构 成本,方法A更为高效(当 n 较大时,方法A更优).</p>
<h2 id="27-尽量少做转型动作"><a href="#27-尽量少做转型动作" class="headerlink" title="27.尽量少做转型动作"></a>27.尽量少做转型动作</h2><p>C++ 总共提供六种形式的转型操作,其中包括两种 “旧式转型” 和四种 “新式转型”.</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">/*旧式转型*/</span></span><br><span class="line"></span><br><span class="line">(T) <span class="function">expression</span></span><br><span class="line"><span class="function"><span class="title">T</span><span class="params">(expression)</span></span></span><br><span class="line"><span class="function"><span class="comment">/*新式转型*/</span></span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"><span class="comment">// const 转换为 non-const</span></span></span><br><span class="line"><span class="function"><span class="keyword">const_cast</span><T><span class="params">( expression )</span></span></span><br><span class="line"><span class="function"><span class="comment">// 用来执行 "安全向下转型" </span></span></span><br><span class="line"><span class="function"><span class="keyword">dynamic_cast</span><T> <span class="params">( expression )</span></span></span><br><span class="line"><span class="function"><span class="comment">// 执行低级转型,例如将 一个 pointer to int 转型为 一个 int</span></span></span><br><span class="line"><span class="function"><span class="keyword">reinterpret_cast</span><T> <span class="params">( expression )</span></span></span><br><span class="line"><span class="function"><span class="comment">//用来强迫隐式转换,例如将 non-const 转换为const ,将 void* 指针转为 typed 指针.</span></span></span><br><span class="line"><span class="function"><span class="keyword">static_cast</span><T> <span class="params">( expression )</span></span></span><br></pre></td></tr></table></figure>
<h2 id="28-避免返回-handles-指向对象内部成分"><a href="#28-避免返回-handles-指向对象内部成分" class="headerlink" title="28. 避免返回 handles 指向对象内部成分"></a>28. 避免返回 handles 指向对象内部成分</h2><figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Point</span>{</span><br><span class="line"> <span class="comment">//...</span></span><br><span class="line">};</span><br><span class="line"><span class="keyword">class</span> <span class="title class_">Rectangle</span>{</span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="function">Point& <span class="title">dosomething</span><span class="params">()</span> <span class="type">const</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> p;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">private</span>:</span><br><span class="line"> Point p;</span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>上面的代码返回了 Point 的引用,这实际上是自相矛盾的,函数被声明为 const,但调用者却依旧能够使用返回的 reference 修改成员变量.</p>
<blockquote>
<p>同样的情况发生在指针,迭代器身上</p>
</blockquote>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//将代码更改为这样是一个好选择吗?</span></span><br><span class="line"><span class="function">Point <span class="title">dosomething</span><span class="params">()</span> <span class="type">const</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> p;</span><br><span class="line"> }</span><br><span class="line"><span class="comment">//还是这个?</span></span><br><span class="line"><span class="comment">//但这可能造成 dangling handles 问题</span></span><br><span class="line"><span class="function"><span class="type">const</span> Point& <span class="title">dosomething</span><span class="params">()</span> <span class="type">const</span> </span>{</span><br><span class="line"> <span class="keyword">return</span> p;</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>上面的方案一是昂贵的时间消耗,而方案二可能带来 dangling handles 问题.</p>
<h2 id="29-考虑-“出现异常”的情况"><a href="#29-考虑-“出现异常”的情况" class="headerlink" title="29. 考虑 “出现异常”的情况"></a>29. 考虑 “出现异常”的情况</h2><h2 id="30-inlining"><a href="#30-inlining" class="headerlink" title="30. inlining"></a>30. inlining</h2><p>当你使用 inling 函数时, 你可以调用它们又不需要承担函数调用所招致的额外开销.除此之外,编译器还可能会对它进行特别优化.<br>但是,且慢,不要过度的使用 inlining ,这会造成程序体积的增大,导致频繁的换页行为,较低高速缓存的集中率.</p>
<figure class="highlight c++"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Person</span>{</span><br><span class="line"> <span class="keyword">public</span>:</span><br><span class="line"> <span class="comment">//隐式声明为 inline</span></span><br><span class="line"> <span class="function"><span class="type">int</span> age <span class="title">const</span><span class="params">( <span class="keyword">return</span> age;)</span></span></span><br><span class="line"><span class="function"> <span class="type">bool</span> <span class="title">sex</span><span class="params">()</span> <span class="type">const</span></span>;</span><br><span class="line">};</span><br><span class="line"><span class="comment">//显式声明为 inline</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">bool</span> <span class="title">Person::sex</span><span class="params">()</span> <span class="type">const</span></span>{</span><br><span class="line"> <span class="keyword">return</span> ...;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<blockquote>
<p>例外,记住: inline 只是对编译器提出申请,并不是一个强制命令</p>
</blockquote>
<h2 id="31-将文件间的编译依存关系将至最低"><a href="#31-将文件间的编译依存关系将至最低" class="headerlink" title="31. 将文件间的编译依存关系将至最低"></a>31. 将文件间的编译依存关系将至最低</h2>
</div>
</article>
<div class="blog-post-comments">
<div id="utterances_thread">
<noscript>Please enable JavaScript to view the comments.</noscript>
</div>
</div>
<div id="footer-post-container">
<div id="footer-post">
<div id="nav-footer" style="display: none">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/archives/">Writing</a></li>
<li><a target="_blank" rel="noopener" href="http://github.com/tblgsn">Projects</a></li>
<li><a href="/about/">About</a></li>
</ul>
</div>
<div id="toc-footer" style="display: none">
<ol class="toc"><li class="toc-item toc-level-2"><a class="toc-link" href="#26-%E5%B0%BD%E5%8F%AF%E8%83%BD%E7%9A%84%E5%BB%B6%E5%90%8E%E5%8F%98%E9%87%8F%E5%AE%9A%E4%B9%89%E5%BC%8F%E7%9A%84%E5%87%BA%E7%8E%B0%E6%97%B6%E9%97%B4"><span class="toc-number">1.</span> <span class="toc-text">26.尽可能的延后变量定义式的出现时间</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#27-%E5%B0%BD%E9%87%8F%E5%B0%91%E5%81%9A%E8%BD%AC%E5%9E%8B%E5%8A%A8%E4%BD%9C"><span class="toc-number">2.</span> <span class="toc-text">27.尽量少做转型动作</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#28-%E9%81%BF%E5%85%8D%E8%BF%94%E5%9B%9E-handles-%E6%8C%87%E5%90%91%E5%AF%B9%E8%B1%A1%E5%86%85%E9%83%A8%E6%88%90%E5%88%86"><span class="toc-number">3.</span> <span class="toc-text">28. 避免返回 handles 指向对象内部成分</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#29-%E8%80%83%E8%99%91-%E2%80%9C%E5%87%BA%E7%8E%B0%E5%BC%82%E5%B8%B8%E2%80%9D%E7%9A%84%E6%83%85%E5%86%B5"><span class="toc-number">4.</span> <span class="toc-text">29. 考虑 “出现异常”的情况</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#30-inlining"><span class="toc-number">5.</span> <span class="toc-text">30. inlining</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#31-%E5%B0%86%E6%96%87%E4%BB%B6%E9%97%B4%E7%9A%84%E7%BC%96%E8%AF%91%E4%BE%9D%E5%AD%98%E5%85%B3%E7%B3%BB%E5%B0%86%E8%87%B3%E6%9C%80%E4%BD%8E"><span class="toc-number">6.</span> <span class="toc-text">31. 将文件间的编译依存关系将至最低</span></a></li></ol>
</div>
<div id="share-footer" style="display: none">
<ul>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.facebook.com/sharer.php?u=https://tblgsn.github.io/effectiveCplusplus20210427.html"><i class="fab fa-facebook fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://twitter.com/share?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&text=Effective C++ 笔记三"><i class="fab fa-twitter fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.linkedin.com/shareArticle?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-linkedin fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://pinterest.com/pin/create/bookmarklet/?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&is_video=false&description=Effective C++ 笔记三"><i class="fab fa-pinterest fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" href="mailto:?subject=Effective C++ 笔记三&body=Check out this article: https://tblgsn.github.io/effectiveCplusplus20210427.html"><i class="fa-solid fa-envelope fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://getpocket.com/save?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-get-pocket fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://reddit.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-reddit fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.stumbleupon.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-stumbleupon fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://digg.com/submit?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&title=Effective C++ 笔记三"><i class="fab fa-digg fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="http://www.tumblr.com/share/link?url=https://tblgsn.github.io/effectiveCplusplus20210427.html&name=Effective C++ 笔记三&description=<p>当你谨慎的设计出 classes (template) 和 function template 之后, 你依旧应该注意一些细节上的东西.</p>
<ul>
<li>条款26: 太早的定义变量可能会导致效率上的拖延</li>
<li>条款27: 过度的使用转型,可能导致代码变慢,难以维护,以及难以理解的错误</li>
<li>条款28: 返回对象的内部数据的 handles ,可能会破坏封装,并留下 危险的handles</li>
<li>条款29: 未考虑异常则可能导致资源的泄漏和数据的败坏</li>
<li>条款30: 过度的 使用inline 可能引起代码的膨胀</li>
<li>条款31: 过度的耦合则可能导致让人不满意的冗长建置时间(build times)"><i class="fab fa-tumblr fa-lg" aria-hidden="true"></i></a></li>
<li><a class="icon" target="_blank" rel="noopener" href="https://news.ycombinator.com/submitlink?u=https://tblgsn.github.io/effectiveCplusplus20210427.html&t=Effective C++ 笔记三"><i class="fab fa-hacker-news fa-lg" aria-hidden="true"></i></a></li>
</ul>
</div>
<div id="actions-footer">
<a id="menu" class="icon" href="#" onclick="$('#nav-footer').toggle();return false;"><i class="fa-solid fa-bars fa-lg" aria-hidden="true"></i> Menu</a>
<a id="toc" class="icon" href="#" onclick="$('#toc-footer').toggle();return false;"><i class="fa-solid fa-list fa-lg" aria-hidden="true"></i> TOC</a>
<a id="share" class="icon" href="#" onclick="$('#share-footer').toggle();return false;"><i class="fa-solid fa-share-alt fa-lg" aria-hidden="true"></i> Share</a>
<a id="top" style="display:none" class="icon" href="#" onclick="$('html, body').animate({ scrollTop: 0 }, 'fast');"><i class="fa-solid fa-chevron-up fa-lg" aria-hidden="true"></i> Top</a>
</div>
</div>
</div>
<footer id="footer">
<div class="footer-left">
Copyright ©
2019-2025
tblgsn
</div>
<div class="footer-right">
<nav>
<ul>
<!--
--><li><a href="/">Home</a></li><!--
--><!--
--><li><a href="/archives/">Writing</a></li><!--
--><!--
--><li><a target="_blank" rel="noopener" href="http://github.com/tblgsn">Projects</a></li><!--
--><!--
--><li><a href="/about/">About</a></li><!--
-->
</ul>
</nav>
</div>
</footer>
</div>
<!-- styles -->
<link rel="preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" crossorigin="anonymous" onload="this.onload=null;this.rel='stylesheet'"/>
<!-- jquery -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js" crossorigin="anonymous"></script>
<!-- clipboard -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.7/clipboard.min.js" crossorigin="anonymous"></script>
<script type="text/javascript">
$(function() {
// copy-btn HTML
var btn = "<span class=\"btn-copy tooltipped tooltipped-sw\" aria-label=\"Copy to clipboard!\">";
btn += '<i class="fa-regular fa-clone"></i>';
btn += '</span>';
// mount it!
$(".highlight table").before(btn);
var clip = new ClipboardJS('.btn-copy', {
text: function(trigger) {
return Array.from(trigger.nextElementSibling.querySelectorAll('.code')).reduce((str,it)=>str+it.innerText+'\n','')
}
});
clip.on('success', function(e) {
e.trigger.setAttribute('aria-label', "Copied!");
e.clearSelection();
})
})
</script>
<script src="/js/main.js"></script>
<!-- search -->
<!-- Baidu Analytics -->
<!-- Cloudflare Analytics -->
<!-- Disqus Comments -->
<!-- utterances Comments -->
<script type="text/javascript">
var utterances_repo = 'TBLGSn/tblgsn.github.io';
var utterances_issue_term = 'url';
var utterances_label = 'Comment';
var utterances_theme = 'github-dark';
(function(){
var script = document.createElement('script');
script.src = 'https://utteranc.es/client.js';
script.setAttribute('repo', utterances_repo);
script.setAttribute('issue-term', 'pathname');
script.setAttribute('label', utterances_label);
script.setAttribute('theme', utterances_theme);
script.setAttribute('crossorigin', 'anonymous');
script.async = true;
(document.getElementById('utterances_thread')).appendChild(script);
}());
</script>
</body>
</html>