|
大家周末好,本次给大家分享的内容是C++里面的初始化列表运用,希望对大家有帮助。 一、引出列表的使用: 1、在介绍列表之前,我们先来看看使用const关键字来修饰类中的成员会有什么事情发生,下面是一段简单代码: #include <stdio.h>& x% q" g, w# r' T' e* Y+ \- k% @- E5 ~0 h$ c class Test{ private:: c+ m0 J" T' [ const int a; public:/ Z9 ~6 k5 ~/ x3 i- B int getA() {8 E' o) w$ q, t, I& _; {/ `6 H return a;+ b4 t7 B5 Y4 L }2 w- j' x1 |% q' D4 U $ ~* b3 |+ `" N }; int main() { return 0; } 编译: root@txp-virtual-machine:/home/txp/c++# g++ test.cpproot@txp-virtual-machine:/home/txp/c++# * E4 E, i5 C- R& |/ k 从编译结果来看,没毛病,完全和正常修饰一个成员一样;为了要显示这里的细节问题,我们来创建一个对象,进而调用类里面的方法来获取成员a的值: #include <stdio.h>class Test{6 g2 B6 E, r- q; U) _' A5 s3 ]" e3 k private: const int a; public:: Z- ?9 }! A5 ]0 \# ~3 r! y$ `0 b int getA()# T( j* q& ^& |7 U {3 R% Z! C+ I+ J9 M) }$ q6 F! F% ` return a; }' d6 H( [, z; U1 |9 M4 p9 F0 I+ p }; int main()' X! x; P3 d& w+ K; M {; P6 N; D" U* j) P/ c1 Y5 o$ k3 b Test t; printf("the t.a is %d\n",t.getA());2 w/ R* m h8 E6 x j5 T9 r return 0;8 j( a( b6 ?/ H- w }. f: H+ `/ X$ b 编译: root@txp-virtual-machine:/home/txp/c++# g++ test.cpp4 N: g3 |% U6 b: z& x. ?2 V$ ]test.cpp:3:7: error: uninitialized const member in ‘class Test’ test.cpp:5:16: note: ‘const int Test::a’ should be initialized const int a; % t; d& m+ N7 Y2 [ 通过编译我们发现他报了一个错误,说成员a没有进行初始化;那么没有初始化,我们就给成员a一个值来进行初始化: #include <stdio.h>! [: K8 U' r/ K; n y, @- @ class Test{ private:6 l; a, o: m+ q U- z7 U5 V const int a;4 d/ [3 r+ |+ @0 O6 E: o2 | public: Test()+ {5 Q; S) O1 `4 s s4 u {# ?! ~3 h4 e% f1 I! F a=666;; y9 o: x# p6 H' ~) O) F5 E } int getA() { return a;6 G) y: D7 r G6 B" k }% V0 s. a! @5 Q. ?- M ; A) m% b5 y3 E8 X, [! @' w. e };: P* R$ g: ?- m M/ o7 @ int main()1 v* r- b* |/ g% C! A5 T { N }, P+ C! v2 z Test t;2 s' w( S# d3 {$ p! i: y4 Q) } printf("the t.a is %d\n",t.getA()); return 0; } 我们是用了无参构造函数对a进行初始化(private里面的成员不能直接初始化,被保护住了,这个知识是基本常识哈),下面编译看看,会有啥现象发生: root@txp-virtual-machine:/home/txp/c++# g++ test.cpptest.cpp: In constructor ‘Test::Test()’: test.cpp:7:6: error: uninitialized const member in ‘const int’ [-fpermissive] Test()" S i/ C/ V. B# C/ C) L ^~~~8 u. L- ~1 Y6 G7 E/ Q6 i% [ test.cpp:5:16: note: ‘const int Test::a’ should be initialized# P! S { @% m# Y, s7 @. ~ const int a;5 E/ j" ^) {! q ^ test.cpp:9:11: error: assignment of read-only member ‘Test::a’ a=666;* j4 {/ M# l- \ 4 ^5 f* q7 o) g' {; o' [9 O! b 和没有const关键字修饰的成员还不一样,上面说a还是要初始化,也就是我们在构造函数体里面对a进行进行初始赋值是行不通的哦,那该如何解决解决这个问题呢?答案来了,就是我们的初始化列表。 二、初始化列表“闪亮登场”: 1、首先我们先来看一下初始haul列表的书写格式: ClassName::ClassName:m1(v1),m2(v1,v2),m3(v3)" O3 A. K5 q6 j4 B( M { . q( L2 m- E6 H: C( S" W& x! Z0 z } 从上面我们可以发现,初始化列表就是在构造函数名称后面且在构造函数体之间。同时这里我们也要注意初始化列表的使用原则: (1)成员的初始化顺序与成员的声明顺序相同。 (2)成员的初始化顺序与初始化列表中的位置无关。 (3)初始化列表优先于构造函数的函数体执行。 我们接着上面那个初始的问题,现在我们使用初始化列表来看看啥情况: #include <stdio.h>2 u/ g1 n* Y7 b class Test{- R% t: V; m$ J! Q% Z( Q5 Y+ W7 t private:3 h; {9 o/ u/ H, q5 ` const int a;6 M# Q; V7 W5 ~1 c public:8 X6 F, r0 p, l4 C t9 z6 N5 e% Y Test():a(666) {+ T: b7 r5 i6 y( i6 k // a=666;: F9 T0 a/ U6 R* N( c0 o } int getA() {3 T$ W0 ~, `3 W# ^ return a;( E) M% C& j7 T1 w" Q: z9 d @ } };, r# N X, b) N- r int main() {3 N7 C3 P' Y: t8 D$ O Test t;0 W" I* D1 b( i) w) O' q k# [ printf("the t.a is %d\n",t.getA());9 K" S/ s8 `* k4 \ return 0; }+ U; w9 k1 [- |0 A4 U% O 编译: root@txp-virtual-machine:/home/txp/c++# g++ test.cpp$ a/ G T/ B; N$ X* ?# v% Iroot@txp-virtual-machine:/home/txp/c++# ls) B5 ?& {7 V( h' c a.out test.cpp5 e' j5 Z3 e9 \ root@txp-virtual-machine:/home/txp/c++# ./a.out the t.a is 666 ; T, ~3 O* f! U5 w 问题被完美解决,是不是心里很开心哈。接下来我们继续举一个上面规则里面说的初始化顺序问题: #include <stdio.h>: Y6 O' G+ a0 v3 `0 g( A* i2 Sclass Value{ private: int b;( p1 t& S9 W7 `. Z$ ~* J public:; A9 t' x5 N7 p7 R7 e! k0 ^ Value(int c)- Y; ~; h0 l" t$ d" g* F& x# X1 S5 z @ {$ B% s$ V- P' }, b( r. D printf("the c is %d\n",c);" v A4 \& O! E6 k3 B) w: d' _8 e b=c;! }1 u0 s$ O& _2 j } int getB() { return b; }: N0 C; X+ G: ? };7 N i! X0 K- o, Q# g- i* Y- ? : ~5 |1 u; K1 E3 j class Test{ private: Value d1; Value d2;% r+ U( W4 p& L* U9 o$ _5 { Value d3; public:/ W; C; D/ M: }. h( \5 g4 P Test():d2(2),d1(1),d3(3): d: \3 e0 \- G+ R' E4 b+ H( O {8 g4 G) q( d5 k8 z0 T, x printf("TXP \n");5 D% [' w8 {+ g }. h0 y; C' X. j. W4 r' E3 e7 B }; K: E5 {2 X0 O/ P# F int main()2 ]/ @2 v W8 d% e% d7 u2 i! f {8 S& b- i/ x% ]8 _1 B8 a" X) @ Test t; return 0; } 编译: root@txp-virtual-machine:/home/txp/c++# g++ test.cpp0 E9 @0 P7 {, W0 P3 G z2 B& Qroot@txp-virtual-machine:/home/txp/c++# ./a.out# Q: k5 W# z! c# r the c is 1 the c is 2 the c is 3 TXP 1 u x! N" ^$ g( l& j( @- ? 6 g6 W6 Z# J! o; `3 ? 从上面的输出结果我们可以初始化的顺序与成员的声明顺序有关,同时他也先于构造函数体的执行。 三、类中的const成员: 现在我们来总结一下在类中使用const关键字来修饰类中的属性时,这时的属性有啥特征: (1)类中的const成员会被分配空间的。 (2)类中的const成员的本质是只读变量。 (3)类中的const成员只能再初始化列表中指定初始值 (4)编译器无法直接得到const成员的初始值,因此无法进入到符号表成为真正意义上的常量(也就是说这里的只读变量,我们还是可以通过一定的手段来改变其值的大小。) 下面我们来看一个例子: #include <stdio.h>( O4 F, b6 a4 g# ~9 g3 y- ?! M& F; M$ S3 Y% j2 w$ I+ _ class Value{- ]) ^ n i% _9 _ private: int b;, w5 p; m- \) H4 }5 X" I public:3 ^, }/ M$ ]1 a' Q4 Z3 t+ R5 v Value(int c)6 b4 p( x5 s' p7 @) {( } {+ m* i' f; D2 D$ `# | printf("the c is %d\n",c); b=c; } int getB()) ?9 W! h3 ]" ?- y q, } { return b; }' |8 v1 n0 d" x6 J+ S0 \* i; n };' r8 c1 {; ~( O! h4 H/ ^8 |; b* ? $ {, _# Q, y/ y. P' X3 M class Test{ private:1 Q2 e' M1 k- s7 Y# p& y3 x" | const int f; G$ e7 x# Y/ a Value d1;& @# V3 F* W7 [: d7 G$ d* o# l Value d2;: V% k6 K+ s( @, Y Value d3; public:3 Q7 Y3 ~) R( V1 a Test():d2(2),d1(1),d3(3),f(888)" G3 y2 c: L8 k$ }# M! ?$ O( g {' k# |( {* I! R" `1 E( Z4 g/ E/ l printf("TXP\n"); }+ z- u; Z& K9 G. M- F! A int getF()) e: u2 q& c4 ` { return f;% D3 r% H/ P4 _1 l } int setF(int i), T. z6 W1 m! Y& L {& Q' b! [9 q/ B, }; i& B# C int *p = const_cast<int*>(&f); *p = i;! a, B- u' _# ?; v/ s } };* p8 c& `2 J/ Z1 T int main() {0 G: V6 \% K6 o) O; h Test t; - b: Q+ i3 s- B0 b. q) G printf("the f is %d\n",t.getF());' R; D5 Q& q7 P) s " Q& t- J. }5 Y2 s% m8 w8 p t.setF(666);* l. r0 H) D: q m ?; R: h+ p* Q ; A7 f; L# @6 |& u3 x# w- S printf("the f is %d\n",t.getF());! n# A7 F1 ?1 R4 o E } 编译: root@txp-virtual-machine:/home/txp/c++# g++ test.cpp( a4 m$ g" @" s: `- Vroot@txp-virtual-machine:/home/txp/c++# ./a.out, K/ }' D" E! i the c is 15 f9 i& k% c. e the c is 2' U( M( _" S& O5 D the c is 35 I. i4 Q- _" Y% N TXP the f is 888 the f is 666 G# j* h2 `0 e9 S3 }0 x5 b$ _ ' k0 L3 m0 `* A; U 通过上面的例子,我们的结论都得到了一一验证。 四、总结: (1)类中可以使用初始化列表对成员进行初始化。 (2)初始化列表先于构造函数体执行。 (3)类中可以定义const成员变量。 (4)const成员变量必须在初始化列表中指定初值。 (5)const成员变量只为只读变量。 以上就是本次的学习分享。纯属个人学习c++的成长之旅。 4 W4 }; j F$ u# w- K+ m6 Y5 |' O |
| 顶一下 |
微信公众号
手机版