|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
/ G) D& S1 M+ r' e: P+ K- i T# @2 i* b4 i6 F9 G$ G* h8 H% S
, R# Z1 P7 l3 o7 W" G学习C++你是否会有以下几点误解?0 n$ i+ S8 _ N0 K& E' b" K9 C8 O% o: _) }
% G c& b! M# q# I& B# L
) k9 G5 {/ U L1. “要理解C++,你必须先学习C” W3 O4 k) `* u. }. q3 d
8 B4 }0 h* I# ?: B @2 V8 U- J
4 D4 w. u5 |8 i/ o; D% y, E2. “C++是一门面向对象的语言”8 Q* K$ V }3 M# I) p- A [ ]7 J9 b% B' A
" w* E, \. M! {5 i, Y! w0 G$ L/ \2 L* d- g/ }& G
3. “为了软件可靠性,你需要垃圾回收”: G! L" m8 h6 u% |9 H" K* x% K' g
1 h- Y& i, E: Z2 C. P4. “为了效率,你必须编写底层代码”3 x1 e. X3 i9 E' b# K- _- X5 R+ p1 _/ Q6 A! V& r& z- z9 T
3 z3 N7 [) w- K ~0 G1 o5. “C++只适用于大型、复杂的程序”) Q6 D* X7 _! C# J- [, [2 u3 j4 W* ]+ Y2 o. Q5 \7 G
w! Q3 Z" h( K& v& r( w; ]8 N
3 Z3 E; { E) |如果你中*了,说明这篇文章适合你看。对某些人,某些任务,在某些时间,其中一些误解曾经只是正确的。然而,在如今的C++,应用广泛使用的最先进的ISO C++ 2011编译器和工具,它们只是误解。
7 Y L k3 |9 k2 W. _0 Q/ j) `7 A! Y
下面来一一解释; R, W* M( H# w
4 x& U1 s# q2 e6 X! r7 g" h' l0 p* j S9 e
, {2 K6 v2 c* O3 L7 `" d误解一:“要理解C++,你必须先学习C”# c& V) b! d$ \: ?5 B+ t2 Z6 b6 n( f* P
2 h/ t! p; C4 U4 W, q$ p E& v. O学习C++基础编程比学习C要容易地多。
4 x, v7 i5 x5 G5 Q
+ |5 y: C+ X! F+ x0 P2 ? g+ FC几乎是C++的一个子集,但是它不是最先要学习的最好的子集,因为C缺少计数支持,类型安全,和易用的标准库,而C++为简单任务提供了这些。9 V6 | V& \4 u6 G
! C& Z# S) n# v4 m7 z1 O6 d8 ?- X. m# |# q# V0 T* N
误解二: “C++是一门面向对象的语言”/ L8 G% F% }" X" y; P
( {* }% N2 h0 D% i9 P' V6 N6 }3 a: j# V R1 k/ I2 b
C++支持OOP和其他编程风格,但它并不局限于狭隘的“面向对象”。它综合地支持了包括面向对象和泛型编程技术。通常,一个问题的最优解决方案,包含不止一种风格(范例)。“最优”,我指的是最短、最易于理解、最有效率和最易于维护等。" ?( K+ `' D( b& ~: _% T
& F% H/ c- x3 w0 q# G. n7 S. p: D. c. q" d' a" w$ Q8 M
k4 k4 r, q. ]: H* i5 w$ ^/ z“C++是一门面向对象的语言”使人们认为C++不是必要的(当与C做比较时),除非你需要一个巨大的类继承层次以及很多须函数(运行时多态)——对很多人和很多问题,这样应用并不合适。相信这个误区导致C++因为不是纯面向对象而遭到谴责;毕竟,如果你把“好”和“面向对象”等同起来,那么C++明显包含了很多不是面向对象的东西,一定会被认为是“不好”。不管是哪种情形,这个误解为不学习C++提供了一个很好的借口
, q# d4 A5 @5 j V' B3 q7 M3 o" }" ?0 F0 J1 y
误解三:“为了软件可靠性,你需要垃圾回收”* G0 q i0 U) u% T& |: f
* ]6 X5 ^$ D7 t" G/ T: a: c1 s ]" L( Q
在回收不再使用的内存上,垃圾回收做的很好,但是并不完美。它并非灵丹妙药。因为内存可以被间接地引用,并且很多资源并不是普通内存。
y _3 R2 ?) V2 F, @& @% N" a& u; \/ X( W+ \. y) y! P0 ~% u- b7 ~ T* I6 a5 j
误解四:“为了效率,你必须编写底层代码”; q$ s' W3 a0 t; ~
{+ {0 ?6 N. `5 F; x& f
' z, A! H/ O+ H( d1 h. N$ U" ^3 {) R许多人相信高效率的代码必须是底层代码。一些人甚至认为底层代码天生就是高效的(“如果代码很丑陋,那它一定很高效!一定有人花费了大量时间和精力来优化它!”)。当然,你仅仅使用底层代码是可以写出高效代码的,并且有时在直接处理机器资源时必须使用底层代码。+ ~% k4 o( H% p* A
6 ^8 i. }; y( T" Q% Y) A, K9 Q/ {* ]4 e6 g; z4 b" T) L; U. X' Q) ?" u0 g
然而,你一定要衡量一下工作是否有价值:现代C++编译器非常高效,而现代机器架构非常复杂。如果必须使用底层代码,一定要通过接口封装起来,以便于使用。通常,通过高层接口封装底层代码,会带来更好的优化(如,避免“滥用”底层代码)。在关注效率的场合,首先尝试用高层抽象来呈现需要的解决方案,而不要不加考虑地使用比特位和指针。
9 ?- X! {! r& F2 @+ Z% O0 d/ n6 t1 C6 k' U3 e7 u r3 ]& M1 t+ ]( u$ m4 x
误解五:“C++只适用于大型、复杂的程序”
Y* ]5 [7 k6 f; n |4 r6 S3 g8 M( C: e* Z. g) Z( k$ N3 z% q9 e b" T' Z
C++是一个巨型的语言。它定义的大小和C#与Java差不多。但是这并不意味着你必须知道每一个细节,或者在每一个程序中都用到所有特性。
3 q1 A5 j, b, Y E/ q4 ^9 S/ z& P U8 o- Z, r" T0 F% a
接下来再说一个C++非常经典的易犯错的案例# D. {. m$ I5 j/ y9 d
9 K/ W3 d, V; |0 D! @- E( M
错误代码:1 m5 ?. R) L; ^; k$ t/ Y' \
/ d6 a6 V1 b9 m* z/ X1 {& ?0 @
R: U* H! b* c# G$ \2 Y E' A0 d: U$ `' z% h
12 bool operator( )(const GUID& _Key1, const GUID& _Key2) const{ return mEMCmp(&_Key1, &_Key2, sizeof(GUID)) == -1; }解释. F% o( x$ h) L; b9 R
/ Q0 A' B; H, q8 P: w, H8 G5 u# |. {9 R: G. ?
1 O g5 U7 @; K8 }3 x8 `0 p不能将 mEMCpy()、strcmp() 以及其他一些标准函数的返回值,和 1、-1 这些具体的数字做比较,因为这些函数的返回值只保证大于 0 或者小于 0(译注:而并不保证大于0就等于1,小于0就等于-1)。+ U! w, K2 l' l$ O4 M5 ^
- k5 b/ S3 j6 H" Q6 J& L5 o
6 T. `& o1 r' ]1 r4 p# M7 |' x* ~上面那段错误的代码可能在很长时间内都能正常工作。不过那仅仅是因为运气好而已,没什么其他原因。某一天你写的函数很可能突然间就崩溃了 —— 比如,你换了一个编译器编译源代码,或者通过其他方式优化了 memcpy() 函数。然后你的代码就不能正常工作了。
4 F' r2 Z9 x: b7 c P1 n" [* R, m* Y1 N6 e! e6 K; {) y; w) n- |& g- g
正确的代码:7 e5 E$ W% e/ H7 k; B) r& h& F* r) R! y
7 t$ j/ L P% F6 _
1 x8 ?# |2 I4 e- u. `6 n3 T5 m' ]8 v( c' ?& K$ v' ?+ v7 v7 s, X& q2 \7 D! Z
12 bool operator( )(const GUID& _Key1, const GUID& _Key2) const{ return memcmp(&_Key1, &_Key2, sizeof(GUID)) < 0; } 4 g$ V! M" {( `4 i/ ? C; O5 L+ z i9 H: ^2 w7 ?7 S
建议& @% N5 C0 X# J2 u+ T9 z4 W& ~ ]
$ P: T) U" i+ k/ D7 ?
不要依赖函数本身的行为。如果文档上说一个函数能返回一个不等于 0 的值,那它就是这么实现的。也就是说这个函数可能返回 -10、2 或者 1024。你可能经常看到函数的返回值就是 -1、0 或者 1,但是这并不能保证它每次都会这么做。, @( v0 j* b6 {. T& d$ t9 d* C+ B6 u( a v& U, R0 E! j
1 e+ X* g: E3 h6 @8 |4 f e! O# o) ?9 f. [
这个错误是通过 PSV-Studio 静态分析工具扫描分析得到的。错误文本如下:V698 表达式 “memcmp(…) == -1“ 是不正确的。这个函数可能的返回值不一定只有“-1”,而可能是任何负数。请考虑到使用 “memcmp(…) < 0 ”来替换。
# @) x& Z7 z7 ?: e |
|