|
一、C++动态内存分配: 在学习c语言的时候,我们一般都是使用库函数malloc()来进行内存的申请分配,然后使用库函数free()来进行释放申请到的内存;现在在c++里面采用了另外一种内存申请的方法:
下面是申请内存的类型: 变量申请格式:3 E r- ^: C5 I4 ~- X8 s/ A3 J8 Z% ^1 I6 Q7 S, Q8 I Type* pointer = new Type;( q$ k. v: W H- _, @) q# n 7 ]. m z& U, p: L# ~ //8 {# d @ }+ D9 l delete pointer& \' k5 q2 X2 z, \' M4 f 7 C$ o$ i3 i. ?/ z) @; x 数组申请格式: ) ?) w, a' }; j, e Type *pointer = new Type[N]; // 0 ^" L! B$ [% Q( T8 ~" c* i delete [] pointer;6 ~, W) v$ \" m+ ^: z9 Q5 n 下面我们来看一个例子: #include <stdio.h>5 o* P+ D( d+ `' N: _int main()% ?+ A0 F/ j" _ { int *p = new int; *p=5;' _. B A) i7 `! r( a5 P5 z *p=*p+10;6 d% z7 t; w+ Y) O ! E7 W9 f, G! W+ j) v printf("p= %p\n",p); printf("*p=%d\n",*p);8 ^9 |* v, c g4 O, k6 \; W7 n' y " E$ v0 y; y5 H0 M delete p;& t" f# @. g+ O* {+ t : y3 |2 D+ x+ j+ C7 R& i' T! V/ C p = new int[10]; for(int i=0;i<10;i++) {1 \/ y8 S2 i9 o9 R p=i+1; printf("p[%d] = %d\n",i,p);$ ~- m& J" W1 i' S7 e } delete [] p;+ q$ _: I! U; o# ?$ O6 B( A return 0; }5 z5 E7 `* Q# W! N" A+ |7 X + j4 F0 r5 d1 r( O6 C 输出结果: p= 0xb6d010*p=15 p[0] = 1$ d$ u# q: f) ^0 y6 ? p[1] = 23 t/ [. I }0 m# E5 y' `7 s p[2] = 31 w# x" y$ I8 m1 t p[3] = 41 F2 N+ S- h3 R# I p[4] = 54 n2 w- X0 w0 j1 W4 Y7 S p[5] = 6 p[6] = 7 p[7] = 8 T) B7 z5 M0 s) h$ } p[8] = 9 p[9] = 109 `9 A7 x4 I% y; B+ r) s! p : |" e l6 [5 W 二、new关键字与malloc函数的区别: 1、new关键字是C++的一部分。2、malloc是由c库函数提供的。 ! H/ a* q, h. [4 w- S( i7 U 3、new关键字以具体类型为单位进行内存分配。- S9 J0 j: j2 r4 }, a9 s 6 L1 X2 ~% W+ d% A+ S' V 4、malloc函数是以字节为单位进行内存分配。 5、new关键在申请单个类型变量时可以进行初始化。 6、malloc 不可以进行内存初始化。; r+ e5 j8 X% f1 Y9 Q! X! q 我们来看使用new关键字是如何进行初始化的: #include <stdio.h>& C- y; v! t; a1 Pint main()/ s" U$ J: U) }& b { int * pi = new int(1); float *pf = new float(2.0f); char *pc = new char('c'); 3 q3 V5 B# b/ K( o8 X! v printf("*pi=%d\n",*pi);# e0 u. F1 Z( X' Z$ s printf("*pf=%f\n",*pf); printf("*pc=%c\n",*pc); ' s: F8 O6 F' r delete pi; delete pf;/ h" s3 b2 b2 P+ G delete pc; return 0;- @, u. n9 j' m6 w8 p0 k % @0 ~) _4 a" P7 Z7 K ) C3 E$ u0 K3 k/ G } 4 Y& J2 P% w) l9 @ 输出结果: *pi=1% u/ T/ j. w4 S6 y*pf=2.0000001 m" C6 y( V. J' `2 h *pc=c 三、c++ 中的命名空间: 在c语言中只有一个全局作用域:
c++中提出了命名空间的概念:
1、下面我们来看一下c++中命名空间的定义: namespace Name - Y9 p0 I9 L, M$ G- y+ e$ {( G{ namespace Internal { 7 o+ @7 E3 a, i, {9 g }5 c# ~+ Z" o& [7 L1 v6 i. Z* c }# z: y; M& x3 e- _0 [' | [6 t; L 2、c++命名空间的使用:
3、代码示例: #include <stdio.h>1 q. c3 h, O. m% ? namespace First1 p. r* o; P/ R2 `, z3 M$ }0 E- T) u8 g { int i =0;$ u) K0 d- l# m5 c, D2 A Q }0 B8 F0 H2 d3 e* A" X }! a & b# J9 f. A/ m2 ? namespace Second% s+ }- j+ b- }! c: ]4 u {2 Q# t1 q- a# m* b% F5 t5 p& t1 n int i =1; namespace Internal# \; _: o1 g6 p8 R; @ {4 J- J9 W r! p* N/ i 4 k9 b# L& Y- Z! V' d# H) e struct Test, R' }4 L0 }" Q+ [1 T { int x;9 S' d* ^8 k& P' o( I( B { int y; };/ m& G" C6 ^" ^0 ~. i % I6 x( B' U0 x } 5 l. g1 I6 j, V* A } int main() { using namespace First; using Second::Internal::Test; * t& a- N. t7 @' M o3 p/ V printf("First::i is %d\n",i); printf("Second::i is %d\n",Second::i); Test i={2,4};7 G+ f% ^/ e6 Z% e* G! o# j9 @ 1 m, `! X, k: O5 Z( v printf("i.x is %d\n",i.x); printf("i.y is %d\n",i.y);/ K0 D$ {. n- [4 I3 P* s# t+ w return 0; }) ~* I I% b: l( F& g3 L 2 O" }5 D6 Q; }0 H 输出结果: First::i is 06 v; Z8 _; A, h6 ]. L2 Q; DSecond::i is 1 i.x is 2 i.y is 4$ i3 D0 A6 k+ Z) y9 k6 t 四、c++中的四种强制类型转换 h# F5 n' I- U- i$ g4 v 强制类型转换类型汇总 static_castconst_cast; t5 N5 V$ m$ U, ?, P( T3 V9 c dynamic_castreinterpret_cast 用法:xxx_cast(Expression) 下面是每种强制类型的具体讲解: 1、static_cast强制类型转换:
代码解析: #include <stdio.h>8 F; K0 c, z9 W8 n6 t/ s, r# _+ d9 e& ~/ E6 f% g$ \( r- L6 M void static_cast_demo()7 A3 D G# r7 N# ~& d# C { int i =55;2 s5 L& J5 N/ B! Q' O char c ='c'; int *pi =&i;) E( m6 @9 X5 X. F; j* a; A char *pc =&pc;5 x" v( f7 }1 l9 a ( P5 l4 S+ ?" S& m8 ~; M c=static_cast<char>(i);% Y) x w7 S; J# [# U1 n# H$ T- N! _ pc=static_cast<char*>(pi); 9 D2 o0 E+ ^# @; B( E6 U! ^ } int main() {6 G h6 p" Y1 G$ V0 W; q static_cast_demo();+ w7 e/ q" W$ P$ [& T 3 }4 G& k! Q, K. H" ~ return 0; }1 X2 a1 `# o" v5 z5 e4 F# ]' ~ 输出结果: t.cpp: In function ‘void static_cast_demo()’:t.cpp:8:16: error: cannot convert ‘char**’ to ‘char*’ in initialization" {6 ~+ T! |7 `! |; }/ W4 L+ ~; w char *pc =&pc; ^ t.cpp:11:29: error: invalid static_cast from type ‘int*’ to type ‘char*’& P ^. X2 E+ U& K7 Q pc=static_cast<char*>(pi); ^# ]( A) D. b7 H9 T 刚好验证了我们上面说的static_cast不能用在基本类型指针之间进行强制转换。 2、const_cast强制类型转换:
代码解析: #include <stdio.h>7 S0 a; W+ ?% v void const_cast_demo()3 _8 b+ q9 C; x6 m/ H7 ^8 O, y {6 j& H8 e6 D( Q% x0 y: Y const int& j =2; int& k = const_cast<int&>(j);% s P3 y$ {1 n const int x = 4; int& y = const_cast<int&>(x); 0 O4 {- _& j) v/ Y; X3 }' B) H int z = const_cast<int>(x);3 k/ l @9 r; X) p' J6 Y: ^ 1 k9 B# b) _3 ?5 P% w( b n k=8; printf("k=%d\n",k); printf("j=%d\n",j);6 b. L, q8 ]( c4 O ! S) Y9 W/ v& F+ z$ x j =12; printf("x=%d\n",x); printf("y=%d\n",y);: \! w/ Z- f5 x1 S, U. r% s9 y; \ printf("&x=%p\n",&x);; _! X& ]: i( X }% J/ w- G( X% x- y int main()5 }' ]( h. G, C6 F. N6 T { const_cast_demo(); return 0; " c3 H" w8 L* k6 ^) J/ b: f }& a; _5 p. h- X5 ^! ?9 Z $ Q- S5 T4 d. J( g/ i d# g2 ?' j 输出结果: t.cpp: In function ‘void const_cast_demo()’:4 J2 ?9 C; T, {5 }9 D7 g/ xt.cpp:11:30: error: invalid use of const_cast with type ‘int’, which is not a pointer, reference, nor a pointer-to-data-member type1 L- C' k7 y: T int z = const_cast<int>(x);8 E3 G' O: V" F% A ^4 X$ i7 @7 }3 n2 y% w6 M7 v& f t.cpp:18:6: error: assignment of read-only reference ‘j’4 K7 C' ?" h' v3 J) r j =12; 通过上面的z转换,我们可以发现它的目标不是指针或者引用,所以报错。 3、reinterpret_cast强制类型转换:
代码解析: #include <stdio.h>) D/ l) K3 Z0 G0 H+ _' _3 G2 g \void reinterpret_cast_demo() {) ]' {( r" L8 g: T+ `8 `9 d1 e C int i =2;( ]0 Q8 p: C# r3 \) F char c = 'c'; int *pi = &i;, m. J8 |- n& i char *pc =&c;" J$ H* `% _/ k9 V pc=reinterpret_cast<char*>(pi);0 K% j% I% i6 v' y pi=reinterpret_cast<int*>(pc);" G; @( m/ ?+ m6 O- ? pi=reinterpret_cast<int*>(i); c=reinterpret_cast<char(i); ' v5 h- W! L( l; Y } int main()8 g, X8 T2 N% i. ^8 H/ d { reinterpret_cast_demo();7 ^2 V+ l, ~$ B 9 r% A' O& G5 `+ B. ~- O return 0; ; b# [% W `. Y$ E; i" D+ y' A1 i }4 r+ I) r. T4 ?4 e" x( \. m7 C; t, Z 输出结果: t.cpp: In function ‘void reinterpret_cast_demo()’:t.cpp:12:28: error: expected ‘>’ before ‘(’ token c=reinterpret_cast<char(i);4 e. A- _( d- B7 |) b; T ^9 [" t4 g! y. h4 @- Z! O t.cpp:12:30: error: invalid cast from type ‘int’ to type ‘char’/ g" x9 d4 G0 c c=reinterpret_cast<char(i);; w% \3 h6 g9 r8 V# ?0 Z9 { 从结果我们可以看到,它用于整数之间的转换,不符合规则,所以报错。 4、dynamic_cast强制类型转换(暂时有些概念没有学到,先记住结论):
代码分析: #include <stdio.h>void dynamic_cast_demo() {( K G4 j: G+ ]3 s/ T3 y int i =2; int *pi=&i; char *pc =dynamic_cast<char*>(pi); F2 ?1 s1 ]0 W / r4 [& x# p; B8 O6 g7 s } T( t( Z$ X; ]8 D4 o( b+ H* N, U int main() X% E9 s: G( A2 X {7 b) A" l0 k; M* r+ ]& I dynamic_cast_demo(); return 0; " F" K# n; ]- J1 g- b$ z. Y } 输出结果: .cpp: In function ‘void dynamic_cast_demo()’:2 ~4 _6 D' `3 z, C* F% [t.cpp:6:39: error: cannot dynamic_cast ‘pi’ (of type ‘int*’) to type ‘char*’ (target is not pointer or reference to class) char *pc =dynamic_cast<char*>(pi); 不符合规则,所以报错。 5、小结: 上面四种类型转换的例子,前三种把错误的地方给屏蔽掉,就是正确的例子,第四种类型转换,暂时继承的概念没有学到,所以这个例子不是很好。 同时内存分配的使用,本次也只是简单的说了一下概念,在真正实操当中,还是有很多要注意的地方,下期文章我们再详细解析。 5 n- I! I0 z+ J% o |
| 顶一下 |
微信公众号
手机版