-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcpp-empty-class-instance-size-not-zero.html
More file actions
241 lines (168 loc) · 11.6 KB
/
cpp-empty-class-instance-size-not-zero.html
File metadata and controls
241 lines (168 loc) · 11.6 KB
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
<!DOCTYPE html>
<html>
<head>
<!-- [[! Document Settings ]] -->
<meta charset="utf-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<!-- [[! Page Meta ]] -->
<title>C++空类实例大小</title>
<meta name="description" content="与机器,人,神共舞 - 编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta name="HandheldFriendly" content="True" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="/assets/images/favicon.ico" >
<!-- [[! Styles'n'Scripts ]] -->
<link rel="stylesheet" type="text/css" href="/assets/css/screen.css" />
<link rel="stylesheet" type="text/css"
href="//fonts.googleapis.com/css?family=Merriweather:300,700,700italic,300italic|Open+Sans:700,400" />
<link rel="stylesheet" type="text/css" href="/assets/css/syntax.css" />
<!-- [[! Ghost outputs important style and meta data with this tag ]] -->
<link rel="canonical" href="/" />
<meta name="referrer" content="origin" />
<link rel="next" href="/page2/" />
<meta property="og:site_name" content="与机器,人,神共舞" />
<meta property="og:type" content="website" />
<meta property="og:title" content="与机器,人,神共舞" />
<meta property="og:description" content="编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta property="og:url" content="/" />
<meta property="og:image" content="/assets/images/cover1.jpg" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="与机器,人,神共舞" />
<meta name="twitter:description" content="编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景" />
<meta name="twitter:url" content="/" />
<meta name="twitter:image:src" content="/assets/images/cover1.jpg" />
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Website",
"publisher": "Tao's Page",
"url": "/",
"image": "/assets/images/cover1.jpg",
"description": "编程,读书,思考,旅行,与机器对话,与人交谈,对神发问,探索,体验人生美丽的风景"
}
</script>
<meta name="generator" content="Jekyll 3.0.0" />
<link rel="alternate" type="application/rss+xml" title="与机器,人,神共舞" href="/rss.xml" />
</head>
<body class="home-template nav-closed">
<div class="nav">
<h3 class="nav-title">Menu</h3>
<a href="#" class="nav-close">
<span class="hidden">Close</span>
</a>
<ul>
<li class="nav-home " role="presentation"><a href="/">Home</a></li>
<li class="nav-about " role="presentation"><a href="/about.html">About</a></li>
<li class="nav-fables " role="presentation"><a href="/tag/machine/">Machine</a></li>
<li class="nav-speeches " role="presentation"><a href="/tag/human/">Human</a></li>
<li class="nav-fiction " role="presentation"><a href="/tag/god/">God</a></li>
<li class="nav-author " role="presentation"><a href="/author/hetao/">Author</a></li>
</ul>
<a class="subscribe-button icon-feed" href="/vocab.html">Apps</a>
</div>
<span class="nav-cover"></span>
<div class="site-wrapper">
<!-- [[! Everything else gets inserted here ]] -->
<!-- default -->
<!-- The comment above "< default" means - insert everything in this file into -->
<!-- the [body] of the default.hbs template, which contains our header/footer. -->
<!-- Everything inside the #post tags pulls data from the post -->
<!-- #post -->
<header class="main-header post-head no-cover">
<nav class="main-nav clearfix">
</nav>
</header>
<main class="content" role="main">
<article class="post tag-machine">
<header class="post-header">
<h1 class="post-title">C++空类实例大小</h1>
<section class="post-meta">
<!-- <a href='/'>Tao He</a> -->
<time class="post-date" datetime="2014-07-30">30 Jul 2014</time>
<!-- [[tags prefix=" on "]] -->
on
<a href='/tag/machine'>Machine</a>
</section>
</header>
<section class="post-content">
<p>在C++中,空类实例的大小不是0,这一点经常让初学者感到困惑。表面上看,一个空类没有任何数据成员,似乎它的实例应该占用0字节的空间。然而,C++标准明确规定,即使是空类,其实例也必须占用非零的内存空间。本文将探讨这一现象背后的原因以及相关的编程实践。</p>
<h4 id="1-内存对齐和对象识别">1. 内存对齐和对象识别</h4>
<p>首先,C++中的对象实例需要在内存中独立存在,以便在运行时能够被正确识别和操作。即使是空类,其实例也需要一个唯一的地址,这样在需要进行类型识别、指针运算或对象比较时,系统能够准确地识别每个对象。这个地址不能与其他对象重叠,否则会导致内存管理问题和未定义行为。</p>
<p>为了实现这一点,C++编译器通常会为空类分配至少一个字节的内存空间。这样,每个空类实例都有一个唯一的地址,确保了对象在内存中的独立性和可识别性。</p>
<h4 id="2-遵循标准和一致性">2. 遵循标准和一致性</h4>
<p>C++标准明确规定,所有对象都必须具有唯一的地址。即使是空类,其实例也不例外。这个要求不仅保证了语言的一致性,还使得编译器实现更为简洁和统一。通过为空类实例分配非零大小的空间,编译器可以避免在处理对象时出现特殊情况,从而简化了编译过程中的对象管理。</p>
<h4 id="3-基类和派生类的设计考虑">3. 基类和派生类的设计考虑</h4>
<p>在面向对象编程中,继承是一个重要的概念。即使一个类是空的,它也可能被设计为基类。考虑以下代码:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Empty</span> <span class="p">{};</span>
<span class="k">class</span> <span class="nc">Derived</span> <span class="o">:</span> <span class="k">public</span> <span class="n">Empty</span> <span class="p">{</span>
<span class="kt">int</span> <span class="n">data</span><span class="p">;</span>
<span class="p">};</span>
</code></pre></div></div>
<p>在这种情况下,如果<code class="language-plaintext highlighter-rouge">Empty</code>类的实例大小是0,那么<code class="language-plaintext highlighter-rouge">Derived</code>类的实例大小就会与其成员<code class="language-plaintext highlighter-rouge">data</code>的大小相同,无法区分<code class="language-plaintext highlighter-rouge">Empty</code>类的基类部分和<code class="language-plaintext highlighter-rouge">Derived</code>类的派生类部分。这会导致对象布局混乱,使得程序难以维护和理解。通过确保<code class="language-plaintext highlighter-rouge">Empty</code>类的实例大小至少为1字节,编译器可以清晰地区分基类部分和派生类部分,保证对象布局的合理性和可预测性。</p>
<h4 id="4-实际应用中的例子">4. 实际应用中的例子</h4>
<p>以下代码示例展示了空类实例的大小:</p>
<div class="language-cpp highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">#include <iostream>
</span>
<span class="k">class</span> <span class="nc">Empty</span> <span class="p">{};</span>
<span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="n">Empty</span> <span class="n">e</span><span class="p">;</span>
<span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Size of empty class instance: "</span> <span class="o"><<</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">e</span><span class="p">)</span> <span class="o"><<</span> <span class="s">" bytes"</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
<span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>输出结果通常为1字节。这验证了编译器为空类实例分配了非零大小的空间,以满足C++标准和编程实践的需求。</p>
<h4 id="5-小结">5. 小结</h4>
<p>C++空类实例的大小不是0,主要原因在于:</p>
<ol>
<li>内存对齐和对象识别:确保每个对象都有唯一的地址。</li>
<li>遵循标准和一致性:简化编译器的实现和对象管理。</li>
<li>基类和派生类的设计考虑:保证对象布局的合理性。</li>
</ol>
<p>通过理解这些原因,开发者可以更好地掌握C++语言的设计原则,并在实际编程中避免潜在的问题。尽管空类看似简单,但其背后的设计考虑反映了C++作为一门复杂且功能强大的编程语言的精妙之处。</p>
</section>
<footer class="post-footer">
<!-- Everything inside the #author tags pulls data from the author -->
<!-- #author-->
<!-- Add Disqus Comments -->
</footer>
</article>
</main>
<aside class="read-next">
<!-- [[! next_post ]] -->
<a class="read-next-story no-cover" href="/what-happens-when-you-type-in-a-url-in-browser">
<section class="post">
<h2>What happens when you type in a URL in browser</h2>
<p>When you type a URL into your browser's address bar and press Enter, a series...</p>
</section>
</a>
<!-- [[! /next_post ]] -->
<!-- [[! prev_post ]] -->
<a class="read-next-story prev no-cover" href="/wstring-vs-string-in-cpp">
<section class="post">
<h2>Understanding `std::string` and `std::wstring` in C++</h2>
<p>When working with C++ strings, it’s essential to understand the difference between std::string and std::wstring,...</p>
</section>
</a>
<!-- [[! /prev_post ]] -->
</aside>
<!-- /post -->
<footer class="site-footer clearfix">
<section class="copyright"><a href="/">与机器,人,神共舞</a> © 2024</section>
</footer>
</div>
<!-- [[! Ghost outputs important scripts and data with this tag ]] -->
<script type="text/javascript" src="https://code.jquery.com/jquery-1.11.3.min.js"></script>
<!-- [[! The main JavaScript file for Casper ]] -->
<script type="text/javascript" src="/assets/js/jquery.fitvids.js"></script>
<script type="text/javascript" src="/assets/js/index.js"></script>
<!-- Add Google Analytics -->
<!-- Google Analytics Tracking code -->
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-78960009-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>