你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++里面的初始化列表运用

[复制链接]
gaosmile 发布时间:2020-7-18 18:15
大家周末好,本次给大家分享的内容是C++里面的初始化列表运用,希望对大家有帮助。
一、引出列表的使用:
1、在介绍列表之前,我们先来看看使用const关键字来修饰类中的成员会有什么事情发生,下面是一段简单代码:
#include <stdio.h>& x% q" g, w# r' T
' e* Y+ \- k% @- E5 ~0 h$ c
class Test{
7 V# P$ m! M+ K, A' mprivate:: c+ m0 J" T' [
     const int a;
- p  E" b+ d% z0 j5 m7 m& t8 Mpublic:/ Z9 ~6 k5 ~/ x3 i- B
     int getA()
! O3 m$ j; Y( a/ _2 ]     {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
};
8 O1 R& G$ P4 `! F* q3 Kint main()
/ z" F0 @1 |3 m3 K7 N9 m6 D: V{
7 k& ^% C9 y7 w/ K" Q7 _# i    return 0;
/ V$ n0 n8 v/ f2 O" I1 f}

: m9 G/ Z& N8 v0 C) }7 a& D
编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
2 ~$ K* f; c$ N- m7 y/ \( x5 _1 E$ `root@txp-virtual-machine:/home/txp/c++#
1 {5 Q1 n# N+ R5 E0 V, \( ~. N/ Z
* E4 E, i5 C- R& |/ k
从编译结果来看,没毛病,完全和正常修饰一个成员一样;为了要显示这里的细节问题,我们来创建一个对象,进而调用类里面的方法来获取成员a的值:
#include <stdio.h>
3 |) _6 }1 q! l
/ B6 W: L( ?7 U' U6 \. _$ M, K1 ?class Test{6 g2 B6 E, r- q; U) _' A5 s3 ]" e3 k
private:
/ z/ \3 `! s4 a4 o6 F     const int a;
. I' h( C0 I# V' G  b# S) mpublic:: 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;
7 R! u3 H  x5 j' X, F. Y     }' d6 H( [, z; U1 |9 M4 p9 F0 I+ p

  o6 o# v/ F/ t- S8 V9 O};
! V  ~) @$ m5 C" j% [- X& M, Rint main()' X! x; P3 d& w+ K; M
{; P6 N; D" U* j) P/ c1 Y5 o$ k3 b
    Test t;
' g' t, S4 @8 F  W6 q    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’
4 o5 \4 }* e' T, htest.cpp:5:16: note: ‘const int Test::a’ should be initialized
  Q6 f) g) ?- m6 r+ ?( ~      const int a;
1 L! _+ _2 S2 ?0 C& Y; a
% t; d& m+ N7 Y2 [
通过编译我们发现他报了一个错误,说成员a没有进行初始化;那么没有初始化,我们就给成员a一个值来进行初始化:
#include <stdio.h>
- r0 T1 _: @/ _$ k0 B6 q! [: K8 U' r/ K; n  y, @- @
class Test{
) ~6 j; d2 Y9 }0 B7 Eprivate:6 l; a, o: m+ q  U- z7 U5 V
     const int a;4 d/ [3 r+ |+ @0 O6 E: o2 |
public:
2 M7 O. N2 a3 v( A( n# G$ {7 n$ O     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
     }
6 j* O* B6 ~, j. C- S  N/ L     int getA()
0 B  k+ T* N) b" R* u- H1 F5 S     {
# u( f0 q/ h! p* O7 e/ S7 w" D         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());
, d; y; J' r' k/ n+ F; v9 ?    return 0;
4 ?' C: ?8 U- @- X0 Q5 G}

  x( J2 ]0 T* C: p
我们是用了无参构造函数对a进行初始化(private里面的成员不能直接初始化,被保护住了,这个知识是基本常识哈),下面编译看看,会有啥现象发生:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp
/ ]/ U+ G2 r1 q  ~& V2 w4 Ytest.cpp: In constructor ‘Test::Test()’:
% e& E7 w4 F! ^9 D7 H1 C) `6 Wtest.cpp:7:6: error: uninitialized const member in ‘const int’ [-fpermissive]
  Z, Z2 L9 P& @      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
                ^
; _4 V) o9 _$ Ztest.cpp:9:11: error: assignment of read-only member ‘Test::a’
: j, L* L1 q& z# p% X* x) D8 `) I, }         a=666;* j4 {/ M# l- \
4 ^5 f* q7 o) g' {; o' [9 O! b
和没有const关键字修饰的成员还不一样,上面说a还是要初始化,也就是我们在构造函数体里面对a进行进行初始赋值是行不通的哦,那该如何解决解决这个问题呢?答案来了,就是我们的初始化列表。
二、初始化列表“闪亮登场”:
1、首先我们先来看一下初始haul列表的书写格式:
ClassName::ClassName:
! B/ M7 M* t" l) g# o# K: e   m1(v1),m2(v1,v2),m3(v3)" O3 A. K5 q6 j4 B( M
  {
' J: g* t2 a% R+ H" d2 ^7 C! h  . q( L2 m- E6 H: C( S" W& x! Z0 z
  }

: B! {0 O4 v6 q6 {
从上面我们可以发现,初始化列表就是在构造函数名称后面且在构造函数体之间。同时这里我们也要注意初始化列表的使用原则:
(1)成员的初始化顺序与成员的声明顺序相同。
(2)成员的初始化顺序与初始化列表中的位置无关。
(3)初始化列表优先于构造函数的函数体执行。
我们接着上面那个初始的问题,现在我们使用初始化列表来看看啥情况:
#include <stdio.h>
$ g( H( A, N5 K: V7 g2 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)
8 n4 ]7 x5 F* T* Z$ J: }. t     {+ T: b7 r5 i6 y( i6 k
       // a=666;: F9 T0 a/ U6 R* N( c0 o
     }
$ L, D. l% j0 F7 b" N. T     int getA()
6 U2 g9 J4 o8 {( g& A0 l* S" X     {3 T$ W0 ~, `3 W# ^
         return a;( E) M% C& j7 T1 w" Q: z9 d  @
     }
) i+ e; y# e0 m& Q3 ?
5 o/ ]9 K; O$ i1 f/ R' U# Q};, r# N  X, b) N- r
int main()
% J2 u- Z0 V* ]& E{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;
' `, j' b0 |, u, m}
+ U; w9 k1 [- |0 A4 U% O
编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp$ a/ G  T/ B; N$ X* ?# v% I
root@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
2 g0 X# `+ B* L. b. Bthe t.a is 666
' \" f- {  t8 Q3 g8 P- h; t$ [; u
; T, ~3 O* f! U5 w
问题被完美解决,是不是心里很开心哈。接下来我们继续举一个上面规则里面说的初始化顺序问题:
#include <stdio.h>: Y6 O' G+ a0 v3 `0 g( A* i2 S

8 l* H" w0 s6 j$ v4 xclass Value{
7 X/ O/ _0 }6 O. o/ a! C# ?private:
$ s7 P9 h7 p, Z% n" A! m4 E, w        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
        }
! |9 N. o$ f7 C, h" B        int getB()
; F1 c6 d: f4 C2 ?7 Y. e        {
6 J! W3 }  Y2 A8 }0 j  ~2 P) n          return b;
) |2 c9 n; U3 r9 C        }: N0 C; X+ G: ?
};7 N  i! X0 K- o, Q# g- i* Y- ?
: ~5 |1 u; K1 E3 j
class Test{
3 p& ?2 u' o( ?! l4 l+ Q+ pprivate:
- N2 s/ r9 e0 `( p        Value d1;
! j+ \' H! F, q1 ^8 e        Value d2;% r+ U( W4 p& L* U9 o$ _5 {
        Value d3;
( C2 Y9 c1 i# w; C, \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

% V8 s% R# I' O) d8 W1 G; u3 E& \9 s4 N};  K: E5 {2 X0 O/ P# F

, x" j2 r0 `3 l& _1 j8 y( Qint main()2 ]/ @2 v  W8 d% e% d7 u2 i! f
{8 S& b- i/ x% ]8 _1 B8 a" X) @
   Test t;
' Z* r0 }: Z. @( p2 U; N
2 C2 B8 C& p( z4 O# @7 E) r   return 0;
, ^$ H# ^; q' \4 X* j; Z1 |* [}
# T7 @/ S0 c* g( F7 x4 i

( u- ~* _$ H) S# t+ _. x
编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp0 E9 @0 P7 {, W0 P3 G  z2 B& Q
root@txp-virtual-machine:/home/txp/c++# ./a.out# Q: k5 W# z! c# r
the c is 1
5 T& K! I: o( m& ?0 F9 ithe c is 2
1 b+ t0 R: n% U2 P$ d& ]" [% Xthe c is 3
4 D4 y1 t" [* d# F9 e, r: I8 vTXP 1 u  x! N" ^$ g( l& j( @- ?

3 e: u: w9 @) E3 P  Z* E
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:
5 t/ u# K4 m" s& E) Z2 F        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);
$ q7 n5 i9 O& v  ~" g           b=c;
# C/ P" A" C% y4 r        }
; _7 T+ C6 W' z2 g8 J        int getB()) ?9 W! h3 ]" ?- y  q, }
        {
7 T+ R  J  z6 Q) |+ J" Y           return b;
2 |2 u1 @( u, G2 Z: [5 Q! Y        }' |8 v1 n0 d" x6 J+ S0 \* i; n
};' r8 c1 {; ~( O! h4 H/ ^8 |; b* ?
$ {, _# Q, y/ y. P' X3 M
class Test{
4 s+ J/ _; U8 W. D9 v! n  ^3 ^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;
  [# f9 q" h& ]+ R* Fpublic: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");
" A# s2 n) Q' T  E        }+ z- u; Z& K9 G. M- F! A
        int getF()) e: u2 q& c4 `
        {
: Q$ Z& d/ w" G/ c1 \# c           return f;% D3 r% H/ P4 _1 l
        }
% `, R) u2 F, Y1 [4 k        int setF(int i), T. z6 W1 m! Y& L
        {& Q' b! [9 q/ B, }; i& B# C
           int *p = const_cast<int*>(&f);
3 i, y7 R( T  X9 v               *p = i;! a, B- u' _# ?; v/ s
        }
& h! H/ y  d! [* q# \1 D! H
8 \( c" b, r& Q" x  q  U};* p8 c& `2 J/ Z1 T
int main()
/ X( N' j9 Z2 @8 h! n- E{0 G: V6 \% K6 o) O; h
   Test t;
% C. _0 t+ `  n! W) U  `- 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
}

3 N% F. Y+ s- |2 Y7 c
编译:
root@txp-virtual-machine:/home/txp/c++# g++ test.cpp( a4 m$ g" @" s: `- V
root@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
; u2 R$ K  q! [# s) gthe f is 888
1 ]. w6 q0 _# ^. w: `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
赞 收藏 评论1 发布时间:2020-7-18 18:15

举报

1个回答
李康1202 回答时间:2020-7-19 09:23:19
顶一下
mark.png
关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
人形机器人运动控制、感知与智能配电
半导体创新技术与应用方向
EE架构与软件定义汽车
12V/48V 汽车智能配电(SPD)
区域控制单元(ZCU)与分区架构
关注我们
st-img 微信公众号
st-img 手机版