|
一、对象的构造顺序: 1、对于局部对象: 当程序执行流到达对象的定义语句时进行构造。下面还是用代码来解析这句话: #include <stdio.h>class Test { private: int mi;; k, V% g* i# l" C% w! }" ^7 J7 s public: Test(int i)/ G; m: l; I3 d/ ? {( p" o1 P+ F0 @% L( B1 u mi=i; printf("Test(int i) is %d\n",mi);- i- ` P- v# H+ Q6 o$ U' l }& u1 S) H6 O% k9 x4 G: D) {0 x Test(const Test& obj)* r& h$ S% {2 n. ^5 M! S {# Q4 K3 z& B, V2 G# R" B$ h7 | mi=obj.mi; printf("Test(const Test&) obj is %d\n",mi);# ^/ J9 o$ k% n2 A } };% h/ V" P7 z4 D4 Z int main()2 W) k$ g' D ?3 h5 Z0 _( h {& F' g9 }8 |( C5 o3 H% S B int i = 0 ;) N' T+ ^% z& E0 P3 o+ M Test a1 =i;//Test(int i):0 while(i<3) {0 A, Q p1 l' \ Test a2 = ++i;//Test(int i):1,2,3* w4 F/ M# h$ F B } if(i<4): B0 R: z: H) I2 C6 j {9 \8 X1 Z% x" m1 D& a Test a = a1; //Test(const Test& obj is :0 } else { M; ^! |2 m. z( r Test a(100); / ?: U' W; [8 M/ V$ O7 n8 r } return 0;$ L: p' @( n. x4 k }1 e/ q, K2 S2 Z7 H& B% \ ( s0 g, |. ]' D: Z: q1 \ 输出结果: Test(int i) is 0Test(int i) is 1 Test(int i) is 2+ P( @/ _" S$ ]7 s3 x" J8 |9 a Test(int i) is 3 Test(const Test& obj) is 0% h$ w0 U% q5 _8 ^ 7 Y% H' R/ x( k- o; b 这里我们可以看出当程序流执行到相应的构造对象的那条执行语句时,就会调用构造函数(或者拷贝构造函数)。goto语句想必大家不陌生,但是都害怕这玩意,下面我们加入goto语句看看会产生什么现象: #include <stdio.h>5 |9 R( A; A1 h9 f: Q6 f( u2 Xclass Test{ private: int mi; public:# c9 u! n6 y& W. C Test(int i) { mi=i;, ]5 t1 e) g9 _/ h( d, R9 h: {9 { printf("Test(int i) is %d\n",mi); }& \1 y6 Y' x$ p6 d Test(const Test& obj) { mi=obj.mi; printf("Test(const Test& obj is %d\n",mi); 1 i' d$ x+ R4 ^; \ } }; int main() {/ g' C# o' p, v" A# z2 t int i = 0; //Test(int i) :0: Z7 v1 k4 t0 n0 s Test a1 = i; while( i <3)$ ~+ j" y- \/ x Z+ g {# w2 ^- P+ a* R9 \ Test a2 = ++i; //Test(int i) :1,2,3 }# r) s/ Z3 O' @2 U! r0 J goto end; if(i <4)/ g4 `1 a8 i+ Q' B0 { {. I3 J* A+ }- L9 q Test a = a1;//Test(const Test&) obj is :0 }4 ^- K6 @1 y) y5 h7 P$ b- q" W else { Test a(100); }4 p( ~/ [# D: Y8 w3 V% P end: return 0; }; K, E0 _% R0 q1 l2 T 输出结果: Test(int i) is 0Test(int i) is 1# M' p- A8 a ?7 L" n Test(int i) is 2 Test(int i) is 3 从结果我们可以看出从if那条语句就被跳过了,没有执行到,这里这样写的目的是为了引出,当你使用goto语句,把对象给屏蔽了,后面你不能使用这个对象了,不然程序会出现大问题: #include <stdio.h>7 R" @& V$ u: ~: N ~: C) sclass Test{2 A% r$ @3 X5 J private: int mi;8 O# u6 K3 \* i% D c1 s public:6 Q; ]# D# y6 h0 P, A1 T. z Test(int i)# f& e# o9 D8 ?- p' q9 m { mi=i; printf("Test(int i) is %d\n",mi);! I- G1 k* b# }# o2 }2 K8 X 6 X+ y4 V/ Z: h5 L }+ F; V. i& @* N) B) k# K Test(const Test& obj)& Z$ [9 x6 R# F9 } V {# ~: v) z- J) ~ mi=obj.mi;' k8 _8 m: U. w- h+ O6 u$ ], S printf("Test(const Test& obj is %d\n",mi);- r. g6 K1 J6 H$ v }9 o G7 J" J: G Z3 d int getMi()4 a: z) k8 ?2 q { return mi; }' h) s2 V5 @- |. q0 K3 b" w9 X };2 c: _. ^3 V; z" ?6 x9 K& k5 [ int main() { int i = 0; //Test(int i) :0 Test a1 = i; while( i <3) {9 ~1 ?) D. K1 P* g1 K, y Test a2 = ++i; //Test(int i) :1,2,3 } goto end;8 z7 \2 r7 k! n Test a(100); end: printf("a.mi is %d\n",a.getMi()); . s$ |% [& G4 U9 G, B3 V% ^! E return 0; }; h) D8 Q" N# i 0 e7 C: J" v6 _9 z; @ a 输出结果: tt.cpp: In function ‘int main()’:tt.cpp:32:1: error: jump to label ‘end’ [-fpermissive]8 x# n& {8 d% @3 i3 b1 L end:' v. \4 F* K0 F2 j, ~! L ^0 y# j3 m# ]; n q tt.cpp:30:6: error: from here [-fpermissive] goto end;3 u+ O; {; R# h ^ tt.cpp:31:12: error: crosses initialization of ‘Test a’ Test a(100);; [& t5 h- B: H ^- q% [( h1 a- R 这里就是上面所说了的,对象被goto语句给屏蔽了,后面就不能使用这个对象来进行操作了。 2、对于堆对象:
代码演示: #include <stdio.h>8 | m( l- Q+ ]& ?! N" {3 y% ]$ O! N class Test { private: int mi;7 \ S0 L3 G: _ l# X public:( L$ s& @4 ]3 O- K Test(int i)4 e8 S' u# o& T% _! h) t. g { mi = i; printf("Test(int i): %d\n", mi); } Test(const Test& obj): o* x* e" r8 L( n1 _' T2 {, c1 x {$ r% ~+ g4 U+ r) f& D, @2 `, M mi = obj.mi; printf("Test(const Test& obj): %d\n", mi); } int getMi() {, l9 B# p" T1 N. D* o! t7 z return mi;$ m1 s* S$ S& c( i$ ^8 O8 x4 P/ _ } }; int main() { int i = 0; Test* a1 = new Test(i); // Test(int i): 0 while( ++i < 10 )1 }6 e& g% j/ _: K, H if( i % 2 )! }# f2 Q! f/ A! M new Test(i); // Test(int i): 1, 3, 5, 7, 9 if( i < 4 ) new Test(*a1);$ I6 a5 \! U& B& ~9 m1 Z else" H1 l3 e r$ [5 \5 ]9 L* ^8 O new Test(100); // Test(int i): 100' z+ ^6 A, ?9 g8 f" x3 r! }' n( g return 0;1 z( T% h/ i* q# y, c# k% Q }4 K' g9 R! O4 T& ? 输出结果: Test(int i): 0Test(int i): 1 Test(int i): 3 Test(int i): 5! m6 `) t ]4 F! c4 ^ ~ Test(int i): 7 Test(int i): 92 O( G" b- H- |. u Test(int i): 100+ {7 N0 V7 j; x( a + O8 l5 [' _* b7 s. q, ^8 ~3 V 3、对于全局对象:
同样还是来看代码示例,这里我创建了几个文件:tes1.cpp test2.cpp test3.cpp test4.cpp test.h;他们的内容如下: test1.cpp: #include "test.h"% K4 H) ?+ m! C- G, OTest t4("t4");! B+ V y& X* w+ o int main()1 ~8 r: N, i0 ]0 T/ q {9 G" ?3 r3 o2 H* A' l- M v' q Test t5("t5"); }" n$ P) }+ M' h& e7 } test2.cpp: #include "test.h"; K$ d, Z; X! L- s1 k. m* n. L% P7 n. ? Test t1("t1"); test3.cpp: #include "test.h"Test t2("t2"); S7 ^0 G3 M6 w" l+ Y 9 q7 P( g# s0 [ ^$ A test4.cpp: #include "test.h"# _9 f- k9 r2 c. i9 ITest t3("t3");, F! u% B7 F0 g& \ 6 |! E2 Z" E3 k# `) q! ~- g- X; f test.h: #ifndef _TEST_H_3 @3 S6 t2 Z6 n- u8 h6 N/ O8 J#define _TEST_H_ / @: t4 C% a2 ~9 Q& O8 z+ a7 Q #include <stdio.h>. g7 S9 v4 \# M2 t$ @ class Test! O3 F X/ O4 {5 W) E { V" O2 v+ _$ A$ F public:6 ?$ ~+ j |0 l2 x% N6 W f Test(const char* s)2 W$ C4 n1 C8 Y# e2 d \1 y4 d { printf("%s\n", s);' h' D! B! a9 c, w4 B& R } };# E: i. ^) \7 Z #endif 5 f1 S/ L. @/ z 最后输出结果: root@txp-virtual-machine:/home/txp# g++ test1.cpp test2.cpp test3.cpp test4.cpp -o put/ {. _9 |3 I! I) N$ e0 Lroot@txp-virtual-machine:/home/txp# ./put0 `7 d# ~" B! c% ^- t5 x t48 D5 a, C3 c7 w- s9 Z t1 t2' g' _* D$ a' w t3; ^ }, M( F! K, V ~# Z t5 4、小结:
二、析构函数: 1、c++的类中可以定义一个特殊的清理函数,叫做析构函数,这个函数的功能与构造函数相反,顾名思义就是销毁的意思了。 2、定义:~ClassName()
代码示例: #include <stdio.h>class Test" D P3 e& D O* M! f5 K( ^ {9 I& Q2 _! T+ m$ y# s# E int mi; public: Test(int i)% W$ X/ g; W( C8 e a { mi = i;$ q4 Z: q' y: ^; T0 o printf("Test(): %d\n", mi); }8 c; c4 x; q/ k0 c- D9 C ~Test() {% V0 S* f2 ^- A2 ?- S5 K/ l5 ?7 y printf("~Test(): %d\n", mi); } };' B2 S* U: @6 C int main() { Test t(1); Test* pt = new Test(2);" i; P& p# [- \. i $ C- o# y7 e- |1 C& D/ s delete pt; return 0; } $ T5 r0 h: t; x7 y' C 输出结果: Test(): 1Test(): 24 W2 ]2 N% D. x& [0 V; v. L& S- L ~Test(): 2( H% G, e. D! } ~Test(): 1$ A& J1 }$ a# b. k" C7 l2 e/ y ! c% L; E1 s' b+ C v* {7 c 3、析构函数的定义准则: 当类中自定义了构造函数,并且析构函数中使用了系统资源(比如说,内存的申请,文件打开),那么就需要自定义析构函数了。 4、小结:
|
微信公众号
手机版