-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.html
1451 lines (1057 loc) · 125 KB
/
index.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
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 6.3.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.png">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon-32x32-next.png">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon-16x16-next.png">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {"hostname":"younif.github.io","root":"/","scheme":"Muse","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":-1,"unescape":true,"preload":true},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
<meta property="og:type" content="website">
<meta property="og:title" content="Youni Blog">
<meta property="og:url" content="https://younif.github.io/index.html">
<meta property="og:site_name" content="Youni Blog">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="Youni">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="https://younif.github.io/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome : true,
isPost : false,
lang : 'zh-CN'
};
</script>
<title>Youni Blog</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<h1 class="site-title">Youni Blog</h1>
<span class="logo-line-after"><i></i></span>
</a>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="main-menu menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-home fa-fw"></i>首页</a>
</li>
<li class="menu-item menu-item-about">
<a href="/about/" rel="section"><i class="fa fa-user fa-fw"></i>关于</a>
</li>
<li class="menu-item menu-item-tags">
<a href="/tags/" rel="section"><i class="fa fa-tags fa-fw"></i>标签<span class="badge">1</span></a>
</li>
<li class="menu-item menu-item-categories">
<a href="/categories/" rel="section"><i class="fa fa-th fa-fw"></i>分类<span class="badge">1</span></a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>归档<span class="badge">9</span></a>
</li>
</ul>
</nav>
</div>
</header>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content index posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/hello-world/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/hello-world/" class="post-title-link" itemprop="url">Youni Blog</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:24:00 / 修改时间:21:52:56" itemprop="dateCreated datePublished" datetime="2022-09-18T21:24:00+08:00">2022-09-18</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>用于记录学习并输出知识。</p>
<p>测试</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%8EIO/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%8EIO/" class="post-title-link" itemprop="url">C++</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:24:00 / 修改时间:22:44:19" itemprop="dateCreated datePublished" datetime="2022-09-18T21:24:00+08:00">2022-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-folder"></i>
</span>
<span class="post-meta-item-text">分类于</span>
<span itemprop="about" itemscope itemtype="http://schema.org/Thing">
<a href="/categories/%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/" itemprop="url" rel="index"><span itemprop="name">编程语言</span></a>
</span>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="字符与字节"><a href="#字符与字节" class="headerlink" title="字符与字节"></a>字符与字节</h1><h1 id="字符串"><a href="#字符串" class="headerlink" title="字符串"></a>字符串</h1><ul>
<li>字符串类库由<code>base_string<></code>模板与几个标准特化版<code>string wstring u16string u32string</code>组成。</li>
<li>string中不以<code>\0</code>判定结尾,所以可以使用string包含任何字符。</li>
<li>转换成c-string:<code>data()</code>、<code>c_str()</code>,结尾包含<code>\0</code></li>
<li>转换成字符数组:<code>copy(char* des, int maxlen, int posStr)</code>,结尾不包含<code>\0</code></li>
</ul>
<h2 id="常用函数"><a href="#常用函数" class="headerlink" title="常用函数"></a>常用函数</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></pre></td><td class="code"><pre><span class="line">string::size_type <span class="comment">//搜索时返回的是该无符号类型,不应该使用有符号int,比较时会出现问题。</span></span><br><span class="line"><span class="keyword">auto</span> idx = filename.<span class="built_in">find</span>(<span class="string">'');</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">string::npos</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">substr(pos,len)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">replace(pos, len, str)</span></span><br><span class="line"><span class="string"></span></span><br><span class="line"><span class="string">find()/find_frist_of() </span></span><br></pre></td></tr></table></figure>
<h2 id="访问"><a href="#访问" class="headerlink" title="访问"></a>访问</h2><ul>
<li><code>[]</code> 不检查有效,无效未定义行为</li>
<li><code>at()</code> 无效时抛出异常</li>
<li>最末字符后存在,且为<code>\0</code>,但<code>at(length)</code> 非法</li>
<li><code>front()</code> 返回<code>[0]</code>,空string时其值为<code>\0</code></li>
<li>空string时,<code>back()</code>未定义</li>
</ul>
<h2 id="比较"><a href="#比较" class="headerlink" title="比较"></a>比较</h2><h2 id="更改"><a href="#更改" class="headerlink" title="更改"></a>更改</h2><ul>
<li><p><code>assign()</code>赋值可以如初始化一样使用多个实参</p>
</li>
<li><p><code>swap(string s)</code>,常量复杂度的成员函数</p>
</li>
<li><p><code>clean()/erase()</code> 清空</p>
</li>
<li><p><code>insert(int pos,string s)</code></p>
</li>
<li><p><code>remove()</code></p>
</li>
<li><p><code>replace()</code></p>
</li>
<li><p><code>erase()</code></p>
</li>
<li><p><code>push_back()</code> 为后插迭代器设置</p>
</li>
<li><p><code>append()</code> 可使用多个实参</p>
</li>
<li><p><code>operator+=()</code></p>
</li>
<li><p><code>resize()</code> 改变字符数量</p>
</li>
</ul>
<h2 id="子字符串"><a href="#子字符串" class="headerlink" title="子字符串"></a>子字符串</h2><ul>
<li><code>substr()</code></li>
<li><code>operator+()</code>,当字符串不再使用时,使用move语义。</li>
</ul>
<h2 id="搜索与查找"><a href="#搜索与查找" class="headerlink" title="搜索与查找"></a>搜索与查找</h2><h1 id="IO"><a href="#IO" class="headerlink" title="IO"></a>IO</h1><h2 id="读取"><a href="#读取" class="headerlink" title="读取"></a>读取</h2><p>读取一串字符:</p>
<p>读取一行字符:</p>
<h2 id="输出"><a href="#输出" class="headerlink" title="输出"></a>输出</h2><p>固定小数位:</p>
<h2 id="切分字符串"><a href="#切分字符串" class="headerlink" title="切分字符串"></a>切分字符串</h2>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E9%9D%A2%E5%90%91%E5%AF%B9%E8%B1%A1/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:21:48 / 修改时间:21:33:51" itemprop="dateCreated datePublished" datetime="2022-09-18T21:21:48+08:00">2022-09-18</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="三大特性"><a href="#三大特性" class="headerlink" title="三大特性"></a>三大特性</h1><h2 id="封装性"><a href="#封装性" class="headerlink" title="封装性"></a>封装性</h2><p>数据和操作封装,只暴露接口,从而获得数据抽象。</p>
<ul>
<li>public定义可在外部访问</li>
<li>protected 可在类的内部和其派生类中访问</li>
<li>private只能在类内访问</li>
<li>继承定义了最小保护区间,与在父类的情况取最严格的属性。严格顺序:<code>public > protected > private</code> 。所以public继承访问控制不变。protected 继承可在类的内部和其派生类中访问。private继承仅可在本类中使用。</li>
</ul>
<h2 id="继承性"><a href="#继承性" class="headerlink" title="继承性"></a>继承性</h2><p>通过继承的方式复用代码。由封装可分为:实现继承、接口继承。</p>
<h2 id="多态性"><a href="#多态性" class="headerlink" title="多态性"></a>多态性</h2><p>通过复写接口代码,使得相同接口可以表现不同。</p>
<ul>
<li><p>重载多态:函数重载</p>
<ul>
<li>name mangling规则:对函数参数与函数名进行编码,生成新的函数名。<ul>
<li>不编码返回值,因为。</li>
<li>顶层const修饰无法区分因为,顶层指针是拷贝。</li>
<li>不同的作用下,同名函数会覆盖。</li>
</ul>
</li>
</ul>
</li>
<li><h2 id="虚函数多态"><a href="#虚函数多态" class="headerlink" title="虚函数多态"></a>虚函数多态</h2></li>
<li><p>模板参数多态</p>
</li>
<li><p>类型多态:强制类型转换</p>
</li>
</ul>
<h1 id="构造与析构"><a href="#构造与析构" class="headerlink" title="构造与析构"></a>构造与析构</h1><h2 id="构造、析构的调用顺序"><a href="#构造、析构的调用顺序" class="headerlink" title="构造、析构的调用顺序"></a>构造、析构的调用顺序</h2><p>由继承深度与派生表顺序依次调用基类构造函数,然后按照类中被声明的顺序依次调用类成员构造函数。<br>析构函数则与之相反。</p>
<h1 id="拷贝构造、赋值"><a href="#拷贝构造、赋值" class="headerlink" title="拷贝构造、赋值"></a>拷贝构造、赋值</h1><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></pre></td><td class="code"><pre><span class="line">Student s;</span><br><span class="line">Student s1 = <span class="number">2</span>; <span class="comment">// 调用拷贝构造函数</span></span><br><span class="line">Student s2;</span><br><span class="line">s2 = s; <span class="comment">// 赋值运算符操作</span></span><br></pre></td></tr></table></figure>
<h2 id="深拷贝和浅拷贝"><a href="#深拷贝和浅拷贝" class="headerlink" title="深拷贝和浅拷贝"></a>深拷贝和浅拷贝</h2><p>值语义与引用语义。值语义在复制后与源对象的内容无关,而引用语义共享同一内部对象。深拷贝指在引用语义下,做值语义复制。浅拷贝则指在引用语义下,只拷贝引用,而共享同一份引用指向的元素。</p>
<h2 id="虚函数与构造、析构"><a href="#虚函数与构造、析构" class="headerlink" title="虚函数与构造、析构"></a>虚函数与构造、析构</h2><p>构造函数不能为虚函数。这是个鸡与蛋的问题,因为构造函数需要设置虚函数表指针,而虚函数通过虚函数表指针获得其确定函数。</p>
<p>如果构造函数中调用虚函数则在编译期绑定为本类函数。因为构造函数必须明确自身所正在构造的对象是什么。</p>
<p>析构函数可以为虚函数,并且在运用运行时多态时需要虚析构函数来调用正确的析构函数。</p>
<h2 id="面试经典问题"><a href="#面试经典问题" class="headerlink" title="面试经典问题"></a>面试经典问题</h2><ul>
<li><p>如果在构造函数中调用memset(this, 0, sizeof(*this))来初始化内存空间,有什么问题吗?</p>
<p>对于有虚函数和虚表存在的类,这会将编译器插入的虚函数表指针等内容清空。</p>
</li>
</ul>
<h1 id="覆盖、重载和隐藏"><a href="#覆盖、重载和隐藏" class="headerlink" title="覆盖、重载和隐藏"></a>覆盖、重载和隐藏</h1><ul>
<li><p>重载:同一作用域、相同函数名、参数列表不同的函数(不关心返回值),方法:函数名重命名。</p>
</li>
<li><p>隐藏(重定义):作用域嵌套、相同函数名,内部作用域函数将外部所有重载函数全覆盖。</p>
</li>
<li><p>覆盖(覆写、重写):派生类中重新定义与父类只有函数体有区别的函数。此时重写虚函数则根据虚函数表指针来调用对应的表中函数,而非虚函数则编译期按类型调用对应函数。</p>
</li>
</ul>
<h1 id="虚函数和纯虚函数"><a href="#虚函数和纯虚函数" class="headerlink" title="虚函数和纯虚函数"></a>虚函数和纯虚函数</h1><p>虚函数将所需要调用的函数与实例化的类所绑定,不与其指针类型所绑定,所以需要在运行时读取器内存,并查找虚函数表来确定需要调用的函数。<br>纯虚函数是未实现的虚函数,当然也可以定义,但是不能实例化,纯虚函数相作为接口名声明。</p>
<h2 id="虚函数与内联"><a href="#虚函数与内联" class="headerlink" title="虚函数与内联"></a>虚函数与内联</h2><p>所调用的虚函数在编译期可确定时可内联,即使用类名指定其函数,此时虚函数不具有多态性。</p>
<h2 id="虚函数与虚继承"><a href="#虚函数与虚继承" class="headerlink" title="虚函数与虚继承"></a>虚函数与虚继承</h2><ul>
<li>相同之处:都利用了虚指针(均占用类的存储空间)和虚表(均不占用类的存储空间)</li>
<li>不同之处:<ul>
<li>虚继承<ul>
<li>虚基类依旧存在继承类中,只占用存储空间</li>
<li>虚基类表存储的是虚基类相对直接继承类的偏移</li>
</ul>
</li>
<li>虚函数<ul>
<li>虚函数不占用存储空间</li>
<li>虚函数表存储的是虚函数地址</li>
</ul>
</li>
</ul>
</li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E7%BC%96%E8%AF%91%E4%B8%8E%E6%89%A7%E8%A1%8C/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E7%BC%96%E8%AF%91%E4%B8%8E%E6%89%A7%E8%A1%8C/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:21:48" itemprop="dateCreated datePublished" datetime="2022-09-18T21:21:48+08:00">2022-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2022-09-13 10:22:36" itemprop="dateModified" datetime="2022-09-13T10:22:36+08:00">2022-09-13</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="宏定义"><a href="#宏定义" class="headerlink" title="宏定义"></a>宏定义</h1><p>宏定义变量一般全部大写,本质是对变量的文本匹配替换,用途:</p>
<ol>
<li>定义宏函数,可在预处理阶段可切换</li>
<li>加#define DEBUG用于控制程序调试。</li>
<li>使用编译器与头文件中的内部的宏变量来处理编译内容<ol start="4">
<li>硬件类型</li>
<li>运行库版本</li>
<li>编译器版本</li>
</ol>
</li>
<li>通过宏变量进行有选择的条件编译</li>
</ol>
<h2 id="编译器调试宏"><a href="#编译器调试宏" class="headerlink" title="编译器调试宏"></a>编译器调试宏</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></pre></td><td class="code"><pre><span class="line">__FUNCTION__ <span class="comment">//函数名</span></span><br><span class="line">__DATE__ <span class="comment">//日期</span></span><br><span class="line">__TIME__ <span class="comment">//时间</span></span><br><span class="line">__LINE__ <span class="comment">//行数</span></span><br><span class="line">__FILE__ <span class="comment">//文件</span></span><br></pre></td></tr></table></figure>
<h1 id="头文件"><a href="#头文件" class="headerlink" title="头文件"></a>头文件</h1><p>头文件包含只能被定义一次的实体、声明的接口信息,如类、const、constexpr、函数声明、变量声明、模板定义、宏变量定义。头文件不应包含using声明,这会有入侵性,在不经意间引入名字而导致名字冲突。为了头文件不重复包含,使用头文件保护符<code>#ifndef NAME #define NAME -------#endif</code> 。</p>
<ul>
<li><p>变量声明和定义区别?</p>
<ul>
<li><p>声明仅把类型提供给编译器,并不为其分配内存空间;定义会为其分配存储空间。</p>
</li>
<li><p>相同变量可以再多处声明(外部变量extern),但只能在一处定义。</p>
</li>
</ul>
</li>
<li><p>模板与头文件</p>
<ul>
<li>当实例化模板时,编译器必须先解析模板,因此需要将模板的声明和定义都放置在同一个.h文件中。而普通的库文件则需要将声明和定义分开,并链接上即可。</li>
</ul>
</li>
</ul>
<h1 id="条件编译"><a href="#条件编译" class="headerlink" title="条件编译"></a>条件编译</h1><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">ifdef</span> /<span class="keyword">ifndef</span> [id]</span></span><br><span class="line"><span class="meta">#<span class="keyword">else</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">endif</span> [id]</span></span><br><span class="line"></span><br><span class="line"><span class="meta">#<span class="keyword">pragma</span></span></span><br></pre></td></tr></table></figure>
<ul>
<li><p>可以通过加#define,并通过#ifdef来判断,将某些具体模块包括进要编译的内容。</p>
</li>
<li><p>应对硬件的设置(机器类型等)。</p>
</li>
<li><p>条件编译功能if也可实现,但条件编译可以减少被编译语句,从而减少目标程序大小。</p>
</li>
</ul>
<h1 id="宏函数"><a href="#宏函数" class="headerlink" title="宏函数"></a>宏函数</h1><ol>
<li><p>多条语句作为独立域可使用<code>do {} while(0)</code>,譬如if后的独立域。</p>
</li>
<li><p>运算对象,在整体之外加上括号<code>()</code></p>
</li>
<li><p>语句过长的情况,可以使用反斜杠<code>\</code></p>
</li>
</ol>
<h2 id="assert"><a href="#assert" class="headerlink" title="assert()"></a><code>assert()</code></h2><p>定义在<code><cassert></code>中,是宏函数。用于确定某些条件,当不成立时快速失败。<code>assert(expr)</code> 对expr求值,如果表达式为假则输出信息并终止程序执行。在程序中不要定义名为assert的任何实体。<br>NDEBUG 预处理变量,如果#define了该变量,则assert什么也不做。也可以在编译时选择该命令行选项。我们也可以根据NDEBUG与<code>#ifdef #endif编写自己的条件调试代码,但是需要在源代码的开头, include <assert.h></code> 之前。</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">define</span> NDEBUG <span class="comment">// 加上这行,则 assert 不可用</span></span></span><br><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><assert.h></span></span></span><br><span class="line"></span><br><span class="line"><span class="built_in">assert</span>( p != <span class="literal">NULL</span> ); <span class="comment">// assert 不可用</span></span><br></pre></td></tr></table></figure>
<h1 id="C-替换预编译"><a href="#C-替换预编译" class="headerlink" title="C++替换预编译"></a>C++替换预编译</h1><p>Inline函数(有编译器的监视)、typedef类型重定义、const常量、条件编译使用template技术来解决</p>
<h3 id="宏函数与函数"><a href="#宏函数与函数" class="headerlink" title="宏函数与函数"></a>宏函数与函数</h3><ul>
<li>宏函数比函数执行更快,因为函数需要跳转到具体调用函地址。<ul>
<li>宏函数属于在结构中插入代码,没有返回值;函数调用具有返回值。</li>
<li>宏函数参数没有类型,不进行类型检查;函数参数具有类型,需要检查类型。</li>
<li>宏函数不要在最后加分号。</li>
</ul>
</li>
</ul>
<h3 id="const"><a href="#const" class="headerlink" title="const"></a>const</h3><ul>
<li>宏替换发生在编译阶段之前,属于文本插入替换;const作用发生于编译过程中,会检查数据类型。</li>
</ul>
<h3 id="typedef"><a href="#typedef" class="headerlink" title="typedef"></a>typedef</h3><ul>
<li>宏主要用于定义常量及书写复杂的内容;typedef主要用于定义类型别名。<ul>
<li>宏替换发生在编译阶段之前,属于文本插入替换;typedef是编译的一部分。</li>
<li>宏不检查类型;typedef会检查数据类型。</li>
<li>宏不是语句,不在在最后加分号;typedef是语句,要加分号标识结束。</li>
<li>注意对指针的操作,typedef char * p_char和#define p_char char *区别巨大。</li>
</ul>
</li>
</ul>
<h3 id="inline"><a href="#inline" class="headerlink" title="inline"></a>inline</h3><ul>
<li>在使用时,宏只做简单字符串替换(编译前)。而内联函数可以进行参数类型检查(编译时),且具有返回值。<ul>
<li>内联函数在运行时可调试,而宏定义不可以。</li>
<li>内联函数本身是函数,强调函数特性,具有重载等功能。</li>
<li>内联函数可以作为某个类的成员函数,这样可以使用类的保护成员和私有成员。而当一个表达式涉及到类保护成员或私有成员时,宏就不能实现了。</li>
<li>内联函数是简单函数、不能递归定义、仅仅是对编译器的建议、应该放在头文件中,这样使用该函数的源文件都会内联、定义在类中的成员函数缺省都是内联的、放在函数声明前面不起inline作用、以代码膨胀为代价</li>
</ul>
</li>
</ul>
<h4 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h4><figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// 定义</span></span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">int</span> <span class="title">functionName</span><span class="params">(<span class="type">int</span> first, <span class="type">int</span> second,...)</span> </span>{<span class="comment">/****/</span>};</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类内定义,隐式内联</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> {</span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">doA</span><span class="params">()</span> </span>{ <span class="keyword">return</span> <span class="number">0</span>; } <span class="comment">// 隐式内联</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类外定义,需要显式内联</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> {</span><br><span class="line"> <span class="function"><span class="type">int</span> <span class="title">doA</span><span class="params">()</span></span>;</span><br><span class="line">}</span><br><span class="line"><span class="function"><span class="keyword">inline</span> <span class="type">int</span> <span class="title">A::doA</span><span class="params">()</span> </span>{ <span class="keyword">return</span> <span class="number">0</span>; } <span class="comment">// 需要显式内联</span></span><br></pre></td></tr></table></figure>
<h1 id="编译"><a href="#编译" class="headerlink" title="编译"></a>编译</h1><h2 id="预处理"><a href="#预处理" class="headerlink" title="预处理"></a>预处理</h2><p>展开宏定义、处理条件编译、处理#include指令、过滤掉注释、添加行号和文件名标识、保留#pragma指令</p>
<h2 id="编译-1"><a href="#编译-1" class="headerlink" title="编译"></a>编译</h2><p>词法分析 - 语法分析 - 语义分析 - 中间语言生成 - 目标代码生成与优化。</p>
<h2 id="链接"><a href="#链接" class="headerlink" title="链接"></a>链接</h2><p>将被编译的二进制文件组装起来成为整体就是链接,这将各个代码段相互的符号地址的引用加以修正。</p>
<ul>
<li><p>静态链接</p>
<p>将库文件链接到最终生成的可执行目标文件中,速度快但浪费内存。静态库生成是对多个目标文件(.o)打包,其包名格式为<code>lib*.a</code>。</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></pre></td><td class="code"><pre><span class="line"><span class="comment">//生成静态库</span></span><br><span class="line">gcc -c test1.c <span class="comment">// 生成test1.o</span></span><br><span class="line">gcc -c test2.c <span class="comment">// 生成test2.o</span></span><br><span class="line">ar cr libtest.a test1.o test2.o</span><br><span class="line"><span class="comment">//使用静态库</span></span><br><span class="line">gcc -o main main.c -ltest</span><br></pre></td></tr></table></figure>
</li>
<li><p>动态链接</p>
<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><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//</span></span><br><span class="line">gcc -fPIC -c test1.c </span><br><span class="line">gcc -fPIC -c test2.c</span><br><span class="line">gcc -shared test1.o test2.o -o libtest.so</span><br><span class="line"><span class="comment">//</span></span><br><span class="line">gcc -o main main.c -ltest</span><br><span class="line"><span class="comment">//默认在环境变量LD_LIBRARY_PATH指定的目录下搜索库文件</span></span><br><span class="line">-Lpath指定搜索库文件的目录</span><br></pre></td></tr></table></figure></li>
</ul>
<h2 id="Makefile"><a href="#Makefile" class="headerlink" title="Makefile"></a>Makefile</h2><p>自动化编译工具,需要用户描述文件之间的依赖关系与相应的更新命令。make工具会检测文件的更新,并自动编译相关的依赖项。如下所述,其中A是目标文件,B是生成A所依赖的所有文件,下方描述了如何使用B去更新A的命令。</p>
<figure class="highlight makefile"><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></pre></td><td class="code"><pre><span class="line"><span class="section">A:B</span></span><br><span class="line">(tab)<command></span><br><span class="line"></span><br><span class="line">test.o : test.c</span><br><span class="line"> gcc -c test.c -o test.o</span><br></pre></td></tr></table></figure>
<ul>
<li>可以在文件中定义”变量名 = 变量值”的形式,之后需要使用这个变量时只需要写一个$符号加上变量名即可,当然,和shell一样,最好用()包裹起语句来。</li>
</ul>
<h1 id="ELF"><a href="#ELF" class="headerlink" title="ELF"></a>ELF</h1><h2 id="定义与作用"><a href="#定义与作用" class="headerlink" title="定义与作用"></a>定义与作用</h2><figure class="highlight shell"><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></pre></td><td class="code"><pre><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">readelf -l a.out <span class="comment">#查看文件的格式和组成</span></span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">objdump -h prog.o //查看一个.o文件</span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">file [file] <span class="comment">#命令通过ELF文件头检查文件类型。</span></span></span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">nm</span> </span><br><span class="line"><span class="meta prompt_">$ </span><span class="language-bash">strip</span></span><br></pre></td></tr></table></figure>
<ul>
<li>Executable and Linkable Format,作为二进制接口(Application Binary Interface,ABI)而开发和发布的。其中<code>.o</code> 可重定位文件、<code>.so</code>共享库(shared library)、<code>.out</code>可执行文件都是使用该格式描述的。</li>
</ul>
<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="number">1</span>) .text section 可执行代码;(只读、可fork后复用)</span><br><span class="line"><span class="number">2</span>) .data section 被初始化的数据;</span><br><span class="line"><span class="number">3</span>) .bss section 未被初始化的数据;(仅描述大小,不占空间)</span><br><span class="line"><span class="number">4</span>) .rec 重定位条目;</span><br><span class="line"><span class="number">5</span>) .symtab 或者 .dynsym section 符号信息;</span><br><span class="line"><span class="number">6</span>) .strtab 或者 .dynstr section 字符串信息;</span><br><span class="line"><span class="number">7</span>) 其他的section,比方满足调试的目的、满足动态链接与加载的目的等。</span><br></pre></td></tr></table></figure>
<h4 id="Text-amp-Data-amp-Bss"><a href="#Text-amp-Data-amp-Bss" class="headerlink" title="Text & Data & Bss"></a>Text & Data & Bss</h4><ul>
<li>.text: 也称为代码段(Code),同时包含一些常量(如一些字符串常量等)。该段内存为静态分配,只读(某些架构可能允许修改),是相同进程共享的。</li>
<li>.data: 全局数据区,也有的地方叫GVAR(global value),用来存放程序中已经初始化的非零全局变量。静态分配。编译时为数据分配空间。<ul>
<li>data又可分为读写(RW)区域和只读(RO)区域。<br>-> 常数区 (RO段)保存不可更改所以也被称为<code>.rodata</code><br>-> 静态区( RW段)则是普通非常量全局变量,静态变量就在其中</li>
</ul>
</li>
<li>.bss: 存放程序中未初始化的和初始化零值的全局变量。静态分配,在程序开始时分配空间且通常会被清零。只占运行时的内存空间而不占文件空间,但记录了大小。</li>
</ul>
<p>text和data段都在可执行文件中,由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。 </p>
<h4 id="堆栈(Heap-amp-Stack)"><a href="#堆栈(Heap-amp-Stack)" class="headerlink" title="堆栈(Heap& Stack)"></a>堆栈(Heap& Stack)</h4><p>堆和栈都是动态分配内存,两者空间大小都是可变的。</p>
<ul>
<li>Stack: 栈,存放Automatic Variables,按内存地址由高到低方向生长,其最大大小由编译时确定,速度快,通常是局部变量,函数参数等的存储区,最大空间不大。</li>
<li>Heap: 堆,自由申请的空间,按内存地址由低到高方向生长,其大小由系统内存/虚拟内存上限决定,速度较慢,但自由性大,可用空间大。<br>每个线程都会有自己的栈,但是堆空间是共用的。</li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E7%BC%96%E7%A8%8B%E5%AE%9E%E8%B7%B5/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E7%BC%96%E7%A8%8B%E5%AE%9E%E8%B7%B5/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:21:48" itemprop="dateCreated datePublished" datetime="2022-09-18T21:21:48+08:00">2022-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2022-09-14 16:24:54" itemprop="dateModified" datetime="2022-09-14T16:24:54+08:00">2022-09-14</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="基本语法"><a href="#基本语法" class="headerlink" title="基本语法"></a>基本语法</h1><ul>
<li>for与while语句,都是先判断条件是否成立,然后再执行循环体</li>
<li>Range-based循环与auto:使用时注意是拷贝还是引用</li>
</ul>
<h1 id="IO"><a href="#IO" class="headerlink" title="IO"></a>IO</h1><ul>
<li>iostream库包含两个基础类型istream(cin)、ostream(cout、cerr、clog)</li>
<li>流操纵符 endl :缓冲刷新操作,结束当前行。注意程序崩溃时,输出可能还在缓冲区中。</li>
<li><code>while(std::cin >>value)</code> 检测cin对象,即检测流的状态。</li>
</ul>
<h1 id="惯用法"><a href="#惯用法" class="headerlink" title="惯用法"></a>惯用法</h1><ul>
<li><p>RAII惯用法 :使用栈对象生命周期管理堆对象生命。</p>
</li>
<li><p>pimpl惯用法 :在接口中不暴露内部实现,降低耦合,分离接口与实现。头文件中仅使用指针或智能指针。</p>
</li>
<li><p>统一初始化:统一的大括号初始化</p>
</li>
</ul>
<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><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//C++ 17注解标签(attributes)</span></span><br><span class="line">[[noreturn]] <span class="function"><span class="type">void</span> <span class="title">loop</span><span class="params">()</span></span>;</span><br><span class="line">[[<span class="built_in">deprecated</span>(<span class="string">"use fun1 instead"</span>)]] <span class="function"><span class="type">void</span> <span class="title">fun</span><span class="params">()</span></span>;</span><br><span class="line">[[fallthrought]] <span class="comment">//switch中故意fall</span></span><br><span class="line">[[nodiscard]] <span class="function"><span class="type">void</span> <span class="title">fun</span><span class="params">()</span></span>; <span class="comment">//必须关注返回值</span></span><br><span class="line">[[maybe_unused]] <span class="comment">//对未使用的函数和参数标记</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//C++ 11的enumerator</span></span><br><span class="line"><span class="keyword">enum class</span> <span class="title class_">Color</span>{ <span class="comment">//给枚举值加命名空间</span></span><br><span class="line"> black,</span><br><span class="line"> white</span><br><span class="line">}</span><br><span class="line">Color::black;</span><br><span class="line"></span><br><span class="line"><span class="comment">//final、override关键字和=default、=delete语法</span></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> <span class="keyword">final</span>{ <span class="comment">//不可继承</span></span><br><span class="line"> <span class="function"><span class="type">void</span> <span class="title">fun</span><span class="params">()</span> <span class="keyword">override</span></span>; <span class="comment">// 表明复写虚函数</span></span><br><span class="line"> <span class="built_in">A</span>() = <span class="keyword">default</span>; <span class="comment">// 使用默认实现</span></span><br><span class="line"> A& <span class="keyword">operator</span>=(<span class="type">const</span> A& a) = <span class="keyword">delete</span>; <span class="comment">// 禁止拷贝</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//C++ 17结构化绑定 </span></span><br><span class="line"><span class="keyword">auto</span> [be, en] = <span class="built_in">equal_range</span>(vec.<span class="built_in">begin</span>(), vec.<span class="built_in">end</span>(), <span class="number">5</span>);<span class="comment">//左开右闭</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//原位构造</span></span><br><span class="line">st.<span class="built_in">emplace</span>();</span><br><span class="line">vec.<span class="built_in">emplace_back</span>();</span><br><span class="line">mp.<span class="built_in">try_emplace</span>(); <span class="comment">//当key存在时,则放弃</span></span><br></pre></td></tr></table></figure>
<h1 id="可变参数函数"><a href="#可变参数函数" class="headerlink" title="可变参数函数"></a>可变参数函数</h1><p>使用va_list,va_start,va_arg,va_end。<br>也可以用宏定义##__VA_ARGS__,可以针对空参数消除逗号 </p>
<h1 id="mian函数前后运行代码"><a href="#mian函数前后运行代码" class="headerlink" title="mian函数前后运行代码"></a>mian函数前后运行代码</h1><p>定义在main( )函数之前的全局对象、静态对象的构造函数在main( )函数之前执行。<code>atexit()</code>在main之后运行。</p>
<h1 id="限定栈、堆创建"><a href="#限定栈、堆创建" class="headerlink" title="限定栈、堆创建"></a>限定栈、堆创建</h1><ul>
<li><p>静态建立一个类对象,由编译器分配内存、管理对象的整个生命周期。设置类的析构函数为私有的或保护的,编译器无法调用析构函数来释放内存。类中必须提供一个destory函数,来进行内存空间的释放,可以在内部直接调用类的构造函数。 </p>
</li>
<li><p>动态建立类对象,是使用new运算符将对象建立在堆空间中。将operator new()设为私有则不能再堆上建立对象。</p>
</li>
</ul>
<h1 id="内存拷贝函数"><a href="#内存拷贝函数" class="headerlink" title="内存拷贝函数"></a>内存拷贝函数</h1><p>手写strcpy、memcpy、strncpy、memset、memmove<a target="_blank" rel="noopener" href="https://blog.csdn.net/qq_42914703/article/details/103323159">LINK</a></p>
<ul>
<li><p>判断地址是否为空 </p>
</li>
<li><p>目的地址和源地址重合的问题,拷贝前要判断目标首地址是否在原拷贝区间内。如果正向拷贝会立刻覆盖原内容,那就反向拷贝。</p>
</li>
<li><p>拷贝到’\0’时就会终止,要保证最终dest末尾是’\0’、因此要先保存dest的地址,便于最终返回。</p>
</li>
<li><p>即是未遇到原串的’\0’,如果已经复制了n个字符(n为提供的参数长度),复制同样会终止。</p>
</li>
<li><p>实现这个函数时一般要把原来的指针类型转换成char*</p>
</li>
</ul>
<h1 id="全局对象初始化顺序"><a href="#全局对象初始化顺序" class="headerlink" title="全局对象初始化顺序"></a>全局对象初始化顺序</h1><h1 id="宏函数"><a href="#宏函数" class="headerlink" title="宏函数"></a>宏函数</h1><ul>
<li>如何得到一个结构体内成员的偏移量?</li>
</ul>
<figure class="highlight c"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">#<span class="keyword">include</span> <span class="string"><stddef.h></span></span></span><br><span class="line"><span class="meta">#<span class="keyword">define</span> offsetof(s,m) ((::size_t)&reinterpret_cast<span class="string"><char const volatile&></span>((((s*)0)->m)))</span></span><br></pre></td></tr></table></figure>
<ul>
<li>手写如何通过一个结构体的成员变量得到一个结构体的地址?<br><img src="https://tva1.sinaimg.cn/large/e6c9d24egy1h16rjezwc1j20kc01nmxf.jpg" alt="img"></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E6%8C%87%E9%92%88/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E6%8C%87%E9%92%88/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:21:48" itemprop="dateCreated datePublished" datetime="2022-09-18T21:21:48+08:00">2022-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2022-09-01 12:52:48" itemprop="dateModified" datetime="2022-09-01T12:52:48+08:00">2022-09-01</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="指针"><a href="#指针" class="headerlink" title="指针"></a>指针</h1><h2 id="指针类型"><a href="#指针类型" class="headerlink" title="指针类型"></a>指针类型</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><span class="line">8</span><br><span class="line">9</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">const</span> <span class="type">int</span> a; <span class="comment">//常量</span></span><br><span class="line"><span class="type">int</span> <span class="type">const</span> a; <span class="comment">//常量</span></span><br><span class="line"><span class="type">const</span> <span class="type">int</span> *a; <span class="comment">//指针常量,不可通过指针所指向的内容</span></span><br><span class="line"><span class="type">int</span> * <span class="type">const</span> a; <span class="comment">//常量指针,不可改变指针指向</span></span><br><span class="line"><span class="type">int</span> *p[<span class="number">10</span>]; <span class="comment">//数组中的元素为指针</span></span><br><span class="line"><span class="built_in">int</span> (*p)[<span class="number">10</span>]; <span class="comment">//指针指向数组</span></span><br><span class="line"><span class="function"><span class="type">int</span> *<span class="title">p</span><span class="params">(<span class="type">int</span>)</span></span>; <span class="comment">//函数,返回int指针</span></span><br><span class="line"><span class="built_in">int</span> (*p)(<span class="type">int</span>); <span class="comment">//指针函数</span></span><br><span class="line"><span class="built_in">Type</span> (*<span class="built_in">function</span> (parameter_list)) [dimension] <span class="comment">//返回数组指针的函数</span></span><br></pre></td></tr></table></figure>
<ul>
<li><code>char * const *(*next)()</code> 是什么类型?<br>以符号开始,从内向外,从右向左解析:是一个指针、指向一个函数,函数签名为<code>char * const * fun()</code>,返回类型是指针,指针类型为常量,指向一个字符指针。</li>
<li><code>int(*f(int,void(*)()))(int,int)</code>是什么类型?<br>一个函数,参数为int和指向返回值为void的无参数的函数指针,返回指针。指向参数为int和int,返回值为int的函数</li>
<li>数组名不是指针,但是当传参时会转换成首元素指针,支持自增操作,不支持<code>sizeof</code>运算。</li>
<li>野指针指未初始化的指针,悬空指针指所指对象已不存在的指针。</li>
</ul>
<h2 id="RAII与智能指针"><a href="#RAII与智能指针" class="headerlink" title="RAII与智能指针"></a>RAII与智能指针</h2><p>RAII即资源获取就是初始化,利用栈对象的生命周期来控制资源释放问题。<br><code>#include <memory></code></p>
<ul>
<li><code>shared_ptr</code> 允许多个指针指向同一个对象,引用计数<ul>
<li><code>weak_ptr</code> 弱引用,不增加引用计数,指向<code>shared_ptr</code>管理的对象</li>
</ul>
</li>
<li><code>unique_ptr</code> 独占对象</li>
</ul>
<h2 id="pimpl"><a href="#pimpl" class="headerlink" title="pimpl"></a>pimpl</h2><p>类的组合方法:在类中不直接放子类成员,通过子类指针与构造函数初始化指针来获得与使用子类。<br><strong>降低耦合、编译依赖。</strong>原类的头文件一般不会被改变,因为类中只有一个指针抽象。此时对子类修改时,不需要重新编译原类。</p>
<h2 id="指针与引用"><a href="#指针与引用" class="headerlink" title="指针与引用"></a>指针与引用</h2><p>引用不是对象,不能定义引用的引用(否则就是引用的别名了)。定义引用时必须初始化为有效值,并保持其引用的对象在引用的生命期内一直有效,sizeof`所得的大小是引用对象的大小。<br>指针是对象,保存着另一个对象的地址,在所指向的对象无效时可以将指针置为nullptr,使用时要注意指针的有效性。而引用暗含了其引用对象的有效,当引用对象可能会无效,请使用指针并在无效时设为nullptr。</p>
<ul>
<li><code>operator[]</code>应该总是返回引用。std库在使用[]时默认所取元素有效。</li>
<li>不以多态的方式处理数组,因为指针移动时按照指针的静态类型大小移动。删除数组也是会通过指针类型来计算大小。</li>
<li>数组指针移动:<code> *(arr + 1) or *(&arr + 1)</code>数组首元素指针加一移动一个元素长度,数组引用移动一个数组长度。</li>
<li>左值引用为常规引用,使用对象的空间,一般表示对象的身份。右值引用,一般是临时量,会窃取值空间。</li>
<li>引用折叠<ul>
<li><code>X& &</code>、<code>X& &&</code>、<code>X&& &</code> 可折叠成 <code>X&</code></li>
<li><code>X&& &&</code> 可折叠成 <code>X&&</code></li>
</ul>
</li>
</ul>
<h2 id="类型转换"><a href="#类型转换" class="headerlink" title="类型转换"></a>类型转换</h2><p>请使用C++的转型操作符,因为旧的C转型语法结构导致意图不精确。</p>
<h3 id="static-cast"><a href="#static-cast" class="headerlink" title="static_cast"></a>static_cast</h3><ul>
<li>主要用于非多态类型的转换,如转换数值数据类型(如 float -> int)</li>
<li>也可用于子类转化为父类。在父类转化为子类时不安全,因为不执行运行时类型检查。</li>
<li>不能转换掉expression的const、volatile和__unaligned属性。</li>
</ul>
<h3 id="dynamic-cast"><a href="#dynamic-cast" class="headerlink" title="dynamic_cast"></a>dynamic_cast</h3><ul>
<li>用于多态类型的转换,所以只适用于指针或引用,会执行行运行时类型检查。</li>
<li>在对应的虚表中的RTTI去查找对应的类型来判断可不可以进行相应的转换。</li>
</ul>
<h5 id="bad-cast"><a href="#bad-cast" class="headerlink" title="bad_cast"></a>bad_cast</h5><ul>
<li>强制转换为指针类型失败,返回 nullptr,不引发异常</li>
<li>强制转换为引用类型失败,引发 bad_cast 异常。</li>
</ul>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">try</span> { </span><br><span class="line"> Circle& ref_circle = <span class="built_in">dynamic_cast</span><Circle&>(ref_shape); </span><br><span class="line">} </span><br><span class="line"><span class="built_in">catch</span> (bad_cast b) { </span><br><span class="line"> cout << <span class="string">"Caught: "</span> << b.<span class="built_in">what</span>(); </span><br><span class="line">} </span><br></pre></td></tr></table></figure>
<h3 id="const-cast"><a href="#const-cast" class="headerlink" title="const_cast"></a>const_cast</h3><ul>
<li>用于删除 const、volatile 和 __unaligned 特性(如将 const int 类型转换为 int 类型 )</li>
</ul>
<h3 id="reinterpret-cast"><a href="#reinterpret-cast" class="headerlink" title="reinterpret_cast"></a>reinterpret_cast</h3><ul>
<li>位的重新解释,允许任何类型之间的转换,危险</li>
<li>但无法删除 const、volatile 或 __unaligned(可按照非对齐访问) 特性。 </li>
<li>一个实际用途是在哈希函数中,通过让两个不同的值几乎不以相同的索引结尾的方式将值映射到索引。</li>
</ul>
<h2 id="类型安全"><a href="#类型安全" class="headerlink" title="类型安全"></a>类型安全</h2><p>类型安全语言是一种只能对数据执行的操作是数据类型所允许的操作。类型安全的代码不会试图访问自己没被授权的内存区域。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E5%91%BD%E5%90%8D%E7%A9%BA%E9%97%B4/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-09-18 21:21:48" itemprop="dateCreated datePublished" datetime="2022-09-18T21:21:48+08:00">2022-09-18</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">更新于</span>
<time title="修改时间:2022-07-07 15:41:15" itemprop="dateModified" datetime="2022-07-07T15:41:15+08:00">2022-07-07</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h1 id="命名空间"><a href="#命名空间" class="headerlink" title="命名空间"></a>命名空间</h1><h2 id="using-声明"><a href="#using-声明" class="headerlink" title="using 声明"></a>using 声明</h2><p>头文件不应包含using声明,这会有入侵性,在不经意间引入名字,隐含着名字冲突。</p>
<p>用于只引入对应命名空间的一个成员。它使得我们可以清楚知道程序中所引用的到底是哪个名字。如:</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> namespace_name::name;</span><br></pre></td></tr></table></figure>
<h3 id="构造函数的-using-声明"><a href="#构造函数的-using-声明" class="headerlink" title="构造函数的 using 声明"></a>构造函数的 using 声明</h3><p>在 C++11 中,派生类能够重用其直接基类定义的构造函数。</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> <span class="title class_">Derived</span> : Base {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="keyword">using</span> Base::Base;</span><br><span class="line"> <span class="comment">/* ... */</span></span><br><span class="line">};</span><br></pre></td></tr></table></figure>
<p>如上 using 声明,对于基类的每个构造函数,编译器都生成一个与之对应(形参列表完全相同)的派生类构造函数。生成如下类型构造函数:</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Derived</span>(parms) : <span class="built_in">Base</span>(args) { }</span><br></pre></td></tr></table></figure>
<h4 id="using-指示"><a href="#using-指示" class="headerlink" title="using 指示"></a>using 指示</h4><p><code>using 指示</code> 使得某个特定命名空间中所有名字都可见,这样我们就无需再为它们添加任何前缀限定符了。如:</p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> namespace_name name;</span><br></pre></td></tr></table></figure>
<h4 id="尽量少使用-using-指示-污染命名空间"><a href="#尽量少使用-using-指示-污染命名空间" class="headerlink" title="尽量少使用 using 指示 污染命名空间"></a>尽量少使用 <code>using 指示</code> 污染命名空间</h4><blockquote>
<p>一般说来,使用 using 命令比使用 using 编译命令更安全,这是由于它<strong>只导入了指定的名称</strong>。如果该名称与局部名称发生冲突,编译器将<strong>发出指示</strong>。using编译命令导入所有的名称,包括可能并不需要的名称。如果与局部名称发生冲突,则<strong>局部名称将覆盖名称空间版本</strong>,而编译器<strong>并不会发出警告</strong>。另外,名称空间的开放性意味着名称空间的名称可能分散在多个地方,这使得难以准确知道添加了哪些名称。</p>
</blockquote>
<p>using 使用</p>
<p>尽量少使用 <code>using 指示</code></p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> <span class="keyword">namespace</span> std;</span><br></pre></td></tr></table></figure>
<p>应该多使用 <code>using 声明</code></p>
<figure class="highlight cpp"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> x;</span><br><span class="line">std::cin >> x ;</span><br><span class="line">std::cout << x << std::endl;</span><br></pre></td></tr></table></figure>
<p>或者</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">using</span> std::cin;</span><br><span class="line"><span class="keyword">using</span> std::cout;</span><br><span class="line"><span class="keyword">using</span> std::endl;</span><br><span class="line"><span class="type">int</span> x;</span><br><span class="line">cin >> x;</span><br><span class="line">cout << x << endl;</span><br></pre></td></tr></table></figure>
<h2 id="范围解析运算符"><a href="#范围解析运算符" class="headerlink" title=":: 范围解析运算符"></a>:: 范围解析运算符</h2><h3 id="分类"><a href="#分类" class="headerlink" title="分类"></a>分类</h3><ol>
<li>全局作用域符(<code>::name</code>):用于类型名称(类、类成员、成员函数、变量等)前,表示作用域为全局命名空间</li>
<li>类作用域符(<code>class::name</code>):用于表示指定类型的作用域范围是具体某个类的</li>
<li>命名空间作用域符(<code>namespace::name</code>):用于表示指定类型的作用域范围是具体某个命名空间的</li>
</ol>
<p>:: 使用</p>
<figure class="highlight cpp"><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><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="type">int</span> count = <span class="number">11</span>; <span class="comment">// 全局(::)的 count</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">class</span> <span class="title class_">A</span> {</span><br><span class="line"><span class="keyword">public</span>:</span><br><span class="line"> <span class="type">static</span> <span class="type">int</span> count; <span class="comment">// 类 A 的 count(A::count)</span></span><br><span class="line">};</span><br><span class="line"><span class="type">int</span> A::count = <span class="number">21</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">fun</span><span class="params">()</span></span></span><br><span class="line"><span class="function"></span>{</span><br><span class="line"> <span class="type">int</span> count = <span class="number">31</span>; <span class="comment">// 初始化局部的 count 为 31</span></span><br><span class="line"> count = <span class="number">32</span>; <span class="comment">// 设置局部的 count 的值为 32</span></span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> ::count = <span class="number">12</span>; <span class="comment">// 测试 1:设置全局的 count 的值为 12</span></span><br><span class="line"></span><br><span class="line"> A::count = <span class="number">22</span>; <span class="comment">// 测试 2:设置类 A 的 count 为 22</span></span><br><span class="line"></span><br><span class="line"> <span class="built_in">fun</span>(); <span class="comment">// 测试 3</span></span><br><span class="line"></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h2 id="class与function的名称空间"><a href="#class与function的名称空间" class="headerlink" title="class与function的名称空间"></a>class与function的名称空间</h2><h3 id="在C语言中"><a href="#在C语言中" class="headerlink" title="在C语言中"></a>在C语言中</h3><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="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">Student</span> {</span></span><br><span class="line"> <span class="type">int</span> age; </span><br><span class="line">} S;</span><br><span class="line"><span class="comment">//等价于</span></span><br><span class="line"><span class="class"><span class="keyword">struct</span> <span class="title">Student</span> {</span> </span><br><span class="line"> <span class="type">int</span> age; </span><br><span class="line">};</span><br><span class="line"><span class="keyword">typedef</span> <span class="class"><span class="keyword">struct</span> <span class="title">Student</span> <span class="title">S</span>;</span></span><br></pre></td></tr></table></figure>
<p>此时 <code>S</code> 等价于 <code>struct Student</code>,但两个标识符名称空间不相同。另外还可以定义与 <code>struct Student</code> 不冲突的 <code>void Student() {}</code>。</p>
<h3 id="在C-语言中"><a href="#在C-语言中" class="headerlink" title="在C++语言中"></a>在C++语言中</h3><p>由于<code>C++</code>编译器定位符号的规则(搜索规则)改变,导致不同于C语言。<br>一、如果在类标识符空间定义了 <code>struct Student {...};</code>,使用 <code>Student me;</code> 时,编译器将搜索全局标识符表,<code>Student</code> 未找到,则在类标识符内搜索。即表现为可以使用 <code>Student</code> 也可以使用 <code>struct Student</code>,如下:</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="comment">// cpp</span></span><br><span class="line"><span class="keyword">struct</span> <span class="title class_">Student</span> { </span><br><span class="line"> <span class="type">int</span> age; </span><br><span class="line">};</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">f</span><span class="params">( Student me )</span></span>; <span class="comment">// 正确,"struct" 关键字可省略</span></span><br></pre></td></tr></table></figure>
<p>二、若定义了与 <code>Student</code> 同名函数之后,则 <code>Student</code> 只代表函数,不代表结构体,如下:</p>
<figure class="highlight cpp"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">typedef</span> <span class="keyword">struct</span> <span class="title class_">Student</span> { </span><br><span class="line"> <span class="type">int</span> age; </span><br><span class="line">} S;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">void</span> <span class="title">Student</span><span class="params">()</span> </span>{} <span class="comment">// 正确,定义后 "Student" 只代表此函数</span></span><br><span class="line"></span><br><span class="line"><span class="comment">//void S() {} // 错误,符号 "S" 已经被定义为一个 "struct Student" 的别名</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="type">int</span> <span class="title">main</span><span class="params">()</span> </span>{</span><br><span class="line"> <span class="built_in">Student</span>(); </span><br><span class="line"> <span class="keyword">struct</span> <span class="title class_">Student</span> me; <span class="comment">// 或者 "S me";</span></span><br><span class="line"> <span class="keyword">return</span> <span class="number">0</span>;</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="zh-CN">
<link itemprop="mainEntityOfPage" href="https://younif.github.io/2022/09/18/C++/%E5%86%85%E5%AD%98/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="Youni">
<meta itemprop="description" content="">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="Youni Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/09/18/C++/%E5%86%85%E5%AD%98/" class="post-title-link" itemprop="url">未命名</a>
</h2>
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">