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

c++——类的继承中的访问级别的学习

[复制链接]
gaosmile 发布时间:2020-8-19 16:19
上一篇文章我们介绍了c++中类的继承学习总结;今天我们继续来分享c++中类的继承中的访问级别的学习总结。
一、继承中的访问级别学习:
1、子类是否可以直接访问父类的私用成员吗?
从面向对象理论角度来看:
  • 子类拥有父类的一切属性和行为,也就是说,子类能够直接访问父类的私有成员。
    ' V7 G' [# }- [! U, h) r7 T
从c++的语法角度看:
  • 外界不能直接访问类的private成员,也就是说,子类不能直接访问父类的私用成员。
      a' B2 h6 \& |  F
代码示例:
#include <iostream>
# u" B1 F- e% |: d# U1 a/ Q5 `#include <string>) Q+ Z2 v+ V' ?& E+ y3 H

9 i) S; B; c+ d- o0 ausing namespace std;
; b& e) v; J5 ^, }' x1 z, b2 c
1 |8 l1 h' M8 b, [class Parent
% r$ c+ h7 w2 X2 e{
0 ^3 W; b# m3 w% pprivate:0 p$ d' y0 m, n) i2 V
    int mv;
' F5 _  x* I. ?  Epublic:
  ~' f, t$ s- G) _) Q" k5 }3 h9 ]    Parent()
+ V1 p1 B8 \" C5 J! E# n    {
1 c0 {; \; q  j* ]        mv = 100;
) m+ }( h# j; m: F    }
3 B# R% q+ |+ h9 h7 G   
1 J2 B# J: F$ V4 C    int value(), A8 b( N- _; b5 ~8 y
    {
# ]+ n" S1 @: m        return mv;3 X, D7 |" @$ \) P- q* V9 v3 I6 H
    }
2 K5 t) z% y! F' v, W. X};! j& [% S. G! X! ]& n

/ D0 ]1 ~' B5 W1 q( {. V' b* l7 Aclass Child : public Parent
$ y$ J4 M% Y# m{6 e) |- c2 e9 ~. ], u+ Z" j; N0 I
public:
1 E3 Q: ]2 r' V# j3 `9 O    int addValue(int v)
3 `7 F3 y5 I1 V: W$ M- S5 B( \    {
8 i6 c1 p8 z" J+ v        mv = mv + v;    //  如何访问父类的非公有成员
/ e* S6 H  Z6 l. ?7 N  z" p5 j    }
6 X7 P: O5 [4 v9 ~};+ h6 f# z) v% Q3 N: V* I
) |0 w! [9 J; N* x
int main()
/ S6 }: T/ Z* ~8 g* Q{   
$ U% [5 o8 D) _9 a, k, t8 N. z: ^    return 0;0 ]0 t6 j; s1 o" c8 A
}
5 v9 g; D+ A* ^0 i5 Y1 B
输出结果:
root@txp-virtual-machine:/home/txp# g++ test.cpp  ]/ i2 O) G4 B) [- j& v& r
test.cpp: In member function ‘int Child::addValue(int)’:
- O- D  k/ C& S' Qtest.cpp:9:9: error: ‘int Parent::mv’ is private
* L  M& L( y- m     int mv;" @# A, H7 S& Z7 r+ s
         ^: ]3 A; T0 l: m0 t) h6 o4 i
test.cpp:27:9: error: within this context  w1 R4 z" {8 w4 k% B9 K
         mv = mv + v;    //  如何访问父类的非公有成员
6 V, {; p, t* k( [         ^
, r' Q+ o  j/ f8 Itest.cpp:9:9: error: ‘int Parent::mv’ is private7 ^) v8 i) x/ R, I4 m; A2 V2 H
     int mv;7 O" c" o2 \0 P9 k' k
         ^5 q7 f1 {) l; M4 P0 |6 Y8 c
test.cpp:27:14: error: within this context
! j) @  Z! o1 v6 g1 C3 }1 U         mv = mv + v;    //  如何访问父类的非公有成员
' P* V  W/ w5 f9 a# B& X, z              ^6 z& z9 W, o, O: c6 r

! F4 a! Y& {) I/ i
注解:我们可以看到子类不能直接访问到父类里面的属性
2、继承中的访问级别关系
  • 面向对象中的访问级别不只是public和private
  • 可以定义protected访问级别
  • 关键字protect的意义
        --修饰的成员不能被外界直接访问
    5 Q2 b: C$ G* u3 V3 Y
            -- 修饰的成员可以被子类直接访问
代码实现
#include <iostream>
( j5 x4 m) j5 {/ c4 [#include <string>
# y2 _6 U' x8 M( P% I% l$ B1 [
- }: U; @* x0 nusing namespace std;4 [, S, l8 Z& Y" V1 h3 Q; D9 H

+ y5 G3 X! E& I) p2 dclass Parent: l4 S! B4 D( Y% Z, R% W
{
5 q  {3 I. m- y- P' W( |protected:: J1 ~2 F) P( m# T* ?
    int mv;- p! ~" j1 k( Q  R' q- @& T
public:
! v; [+ ^  X% M  c    Parent()
4 d, g, P1 Y/ ~) R    {# A: \  N. F* j* N8 [# X
        mv = 100;# f) |& ?+ a: x+ X* }1 D/ K8 d4 u
    }
5 R; }$ \; \# A( }! K    : U# Z) G$ |5 c: i8 L1 W2 w
    int value()
5 Q% E1 K- _, c7 X& t    {: U9 [# J# m# U6 K% T
        return mv;
9 M+ ?$ [1 m' j2 M- F) d; h    }# L6 Y- ?6 c- _/ A! a1 A
};
) d7 ?8 W# Q3 {; \4 o0 y% Z
' N) \3 F. r+ E: p3 W1 I% ]: ^class Child : public Parent
$ J' F- `0 D4 i0 ^{' J9 @* E+ F; s; _1 J+ f" P
public:
. N& h/ b. r5 g, k9 J$ _8 q: y3 L+ y    int addValue(int v)
6 ~1 T1 E3 }+ n: @( d, B9 _: s3 w    {
& ]& l6 x) F* y/ |+ \: p. S) Y        mv = mv + v;   
* |* n4 e8 F- s9 o& S; \2 m) o    }
& n3 W: F8 I) Y6 _9 T% d  L};) V% j) o$ c+ R" z0 K/ `: C

. Z% Q' l. P1 V# o; G( gint main()8 g( S$ s) y8 T
{   
' V) i! Y+ t/ }; ]2 O( o8 J+ l    Parent p;/ R7 ?% D2 t0 C5 ]7 {3 U* \- h3 a6 s
   
( W( X2 F# d4 N( ^4 {1 d  p9 z    cout << "p.mv = " << p.value() << endl;
# s+ r. V' o" }! Z   
* K! y' ~4 m3 E+ D0 Y6 o     p.mv = 1000;    // error2 n! v0 w1 s) P& |/ C( U
    . C0 n* T  ^6 r
    Child c;
1 M2 X3 Y+ t, Z    + n" z. v" L  e/ i/ ~4 p' t
    cout << "c.mv = " << c.value() << endl;
; P4 _% M( D8 l( l    1 J% `9 O- H6 o& N
    c.addValue(50);
# q  w  D1 J/ z3 }; b   
3 O2 {# @' M4 m( E0 A  _7 g    cout << "c.mv = " << c.value() << endl;. @; _  h5 ?1 P2 m3 h
    3 y% m6 F& t$ l$ l' ]+ |( _1 f( i
     c.mv = 10000;  // error6 H$ _3 Q4 V2 N/ j8 ~4 A
   
* E2 F  }8 W/ R+ ]    return 0;
0 D8 A" Q1 a. f; g}5 W2 [: D" a8 S( x% W1 {2 ~) b- Q7 {# {
运行结果:
root@txp-virtual-machine:/home/txp# g++ test.cpp5 E) l) R7 ^7 E/ G+ {2 |1 u
test.cpp: In function ‘int main()’:% I' O3 y  R9 h# N/ [/ ^% p
test.cpp:9:9: error: ‘int Parent::mv’ is protected6 {4 R( ?  i& d2 H6 g9 u
     int mv;
! t  {2 ^1 J2 l- o( m         ^
4 A! g* N0 P8 t4 D$ K: G) _; f3 Ttest.cpp:37:8: error: within this context
4 X8 Q+ u2 c+ z, h& _2 ?      p.mv = 1000;    // error, p/ g8 H9 X$ A; f1 U* _
        ^
1 P! ~4 O$ @: B! v/ l0 b2 y- L' Etest.cpp:9:9: error: ‘int Parent::mv’ is protected" W- A: Z/ M# L7 E" k- i! V2 F# Y
     int mv;9 t0 P$ T+ |3 H% t5 H0 Y
         ^
' ]2 ]. A& d6 R' }! T# `4 @& H: Ctest.cpp:47:7: error: within this context  F' _  v1 s- ^4 ]
     c.mv = 10000;  // error& ^& |" r; N( s9 y5 k' h

0 a- U+ V! O4 ]4 s7 s
注解:这里我们把父类的属性private修改成protect,这里我们注意到在子类里面的方法中是可以使用父类中的属性mv了,只不过在int main()函数中,使用父类和子类定义的对象,均不可以对父类中的属性mv进行访问,这一点要注意。
3、为什么面向对象中需要protect?
我们还是用生活中的例子来理解,每个人的个人隐私,是不能泄露的,也就是我们c++中的private关键字;而你身上穿的衣服,每个人都可以知道,也就是c++中的public关键字;最后我们的protect关键字,为啥c++中会需要它,我想还是跟生活中有关(所以说,面向对象的编程,非常贴近生活),比如说,家庭开会,有些事情就不能让外人知道,但是自己家人就可以知道,所以这跟protect关键字的用法非常像,也就是说,protect关键鉴于private和public之间。
4、定义类时访问级别的选择:
微信图片_20200819161828.png
注解:从图中我们可以发现,当有发生继承关系时,就考虑使用protect关键字
5、组合和继承的综合运用
微信图片_20200819161831.png
说明:Object这个类是被用来继承的;Line和Point两个类进行组合。
代码示例:
#include <iostream>
" |# |+ f, ^- h- p3 z8 m5 b, {#include <string>
' N# T8 D) B+ k1 n7 `$ e#include <sstream>
* t; f. N2 j. ?, r
/ a1 J& m; v$ b5 h" v8 eusing namespace std;
; Q' k1 e% P% f5 L; `. \2 W2 G1 k' _# n% P6 n2 r
class Object+ N2 i0 e1 K" w! z7 C5 r$ A- M  d& {- `- d
{' F% [4 Q; l. N% C( L- P0 ]7 ]" o* [
protected:( f% G1 B% N( d  d
    string mName;
' W& h" C. \0 F) j, P/ G    string mInfo;* N, t- T. }2 R% @% |; L3 M  j& H) f
public:
" G3 U, ~- r9 J1 r9 C  S    Object()
9 x% c; D2 H2 l7 A% {* G  ?8 G    {% i, {7 H. X9 r
        mName = "Object";; C7 T! O2 ^- F5 }6 {+ M. R
        mInfo = "";4 D$ l: `# @1 G) Z. |. }: j
    }( l$ j( z2 @4 |4 Y$ O2 s5 j
    string name()
$ W1 X, Z; A; \* l( q    {  z) J( G) {) G) ?4 {  F
        return mName;
! l' y# X, e! k; V# E    }$ E1 C& @6 c  v( E$ Y
    string info()7 y* \7 w# m3 h
    {! F5 V% A: C' b* T% Y" E
        return mInfo;
8 X# K% o5 ~7 |$ F    }
* F& e- b) g! G7 @9 F};3 W8 @: V+ Y' C* C1 t$ n8 y
9 S0 G* ?8 m) U
class Point : public Object9 e/ y9 L: F" [- ], ~8 L
{/ ^3 _2 ]$ z1 z: L/ X, D& h
private:
& y- Y# N+ S& \$ ~8 v% _1 T    int mX;
2 z- J+ U8 t. u# m" L    int mY;1 j0 v1 D" _) o9 Q6 b6 H& S
public:3 g* s& v6 [9 o' B
    Point(int x = 0, int y = 0)1 Y- B; ]6 |# T
    {/ j, D" R9 y: g9 c- }$ f
        ostringstream s;
5 d* R- f' l, J2 y        4 O2 h% l/ B1 R6 S: y: P
        mX = x;1 W* ~- q; c3 u, W, S
        mY = y;
( u( u# g* v! ]' U! l        mName = "Point";
, }* p5 ~4 G4 T  c% `/ U        
! ~! V* l& w5 e+ A% b: [9 K        s << "P(" << mX << ", " << mY << ")";
* c- q; V( j% `) f5 n! x        - O+ N* \) s, ?9 r5 }/ w
        mInfo = s.str();
( ?! i% V! Z. \  Q5 D; t    }4 s" g6 Q" {% `0 Q9 c7 C) Q
    int x()
# z/ w. I6 ?) d; E! ^9 K- y0 w. I    {
# R7 O& `0 t* v        return mX;
) G4 ?0 g; z* l" |  W( n    }
$ I/ {; ]/ V3 l3 t" x5 G    int y()
+ o/ g5 ^" J; H; |    {  s+ z& d6 C, W! {2 I/ r
        return mY;  m4 u9 ]1 T- Y9 f8 b
    }: z2 l) I) |) G
};
9 S+ I; a, |! t( i4 Z7 [$ Q
& Y( S5 q  S3 T6 s4 x. Nclass Line : public Object
" e0 \; w( E3 d9 Z{
3 T( C8 U/ I9 M( bprivate:; U" `6 S- G3 h" L. l; A2 |
    Point mP1;
. x/ X. `' s# V& B! n, L    Point mP2;4 r% V4 S+ L7 y
public:
% P  Z# Y7 k% N& ^! x    Line(Point p1, Point p2)9 w+ c- l: a, L* V; v$ Y$ j
    {5 Q. I( m" x) I: s
        ostringstream s;
  P/ O( i, M  @+ K        ' |- ?% k" B) l( M: _* z
        mP1 = p1;4 D% a# L: T: M' F4 V$ S6 G" }
        mP2 = p2;. q$ R% E2 Z3 i$ s( j
        mName = "Line";
6 ~- T5 Q1 p6 ?. x7 C$ G        
3 b: m5 [  f6 I' Z* j        s << "Line from " << mP1.info() << " to " << mP2.info();! Y- M2 W. ^. x3 X
        / k; t& y8 s1 N0 j3 [
        mInfo = s.str();" S! i  d( m! s$ T3 ~
    }9 A/ E4 T/ I- g5 {* A* \
    Point begin()
4 k0 ^- O4 _9 \    {
5 ^$ |5 [/ U; N9 Y# Z: H        return mP1;$ E  g, W; I/ v% d* t, B; {1 ^
    }1 `% T! I; c- ~2 S, @6 j: y- {
    Point end()) X5 H# p* w, [& m/ K$ }# o7 U
    {
; Z) k) u; I( ^, P        return mP2;
0 _! U1 l0 J4 \) M' t! d    }
% {/ z! x& z; l& b};- y- K3 A' }0 [- ]$ x8 g8 l# n
& F/ e; O  B6 ~6 e1 m$ @" ?
int main()
  U9 d" `7 s% C! |- f, {/ D7 B{   * S# j% h0 L# V% _
    Object o;
, R4 F7 ^. i4 |7 d& S9 T    Point p(1, 2);
+ V5 Y" h: t! \4 E* J  [    Point pn(5, 6);. l, I+ Y  L4 J# M
    Line l(p, pn);+ z; x# H# j+ N0 I( }( @$ R2 p
   
, R/ O. c8 a& J, {5 W2 P    cout << o.name() << endl;
" {" p% X) D0 E2 K% G5 A& y    cout << o.info() << endl;
" S" |" {4 R3 M* E2 P' H9 |9 J" W7 Z; f    ! X+ j9 J) E2 W; h8 @* ]6 v- n
    cout << endl;( Z1 e% `4 m* ]8 T/ D4 A
   
/ O1 G! L* Q9 e+ a# ]" L    cout << p.name() << endl;  D* f+ U! G) w# [+ G
    cout << p.info() << endl;
. U1 _% }+ Q  S5 r" g& e    + L$ O4 d0 C; S6 Z
    cout << endl;/ g( E" v3 Q! ]% e$ ^( {
    ; p) T& _. I4 D# h
    cout << l.name() << endl;
8 ]; U4 ~# Y2 A8 K3 |7 f    cout << l.info() << endl;
4 _4 i/ ~5 ?1 G! G- j4 o+ ?5 _8 R4 R    $ }1 H/ W4 ?+ `0 k) N
    return 0;
& W9 p: u( N1 v}
  s3 t# @8 b$ F" ^
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
; ?3 S1 `- Q: i3 FObject8 ^4 }: v! b: d/ F, c6 Q

9 m4 H  y/ U& X3 ]6 k! _- D/ j6 G9 x, @7 x, |
Point
- e0 Q7 Z* d; p# j' T# LP(1, 2)
& C% b) @' M3 b  i4 k9 h3 O- G* H3 A* {: r1 p1 ]3 d% B
Line( o+ s/ h" _6 C
Line from P(1, 2) to P(5, 6)+ T5 z3 k! y) I4 i& w

) U2 T# F$ a: S0 O; r) l* L
二、总结:
  • 面向对象中的访问级别不只是public和private
  • protected修饰的成员不能别外界所访问
  • protected使得子类能够访问父类的成员
  • protected关键字为了继承而专门设计的
  • 没有protected关键字就无法完成真正代码意义上的代码复用了

    : D1 P  B0 E/ `. E; N

# s) h; ?6 ^( {
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

  Y- v* W) ^2 h" T
赞 收藏 评论0 发布时间:2020-8-19 16:19

举报

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