|
上一篇文章我们介绍了c++中类的继承学习总结;今天我们继续来分享c++中类的继承中的访问级别的学习总结。 一、继承中的访问级别学习: 1、子类是否可以直接访问父类的私用成员吗? 从面向对象理论角度来看:
从c++的语法角度看:
代码示例: #include <iostream>#include <string>) Q+ Z2 v+ V' ?& E+ y3 H using namespace std; class Parent { private:0 p$ d' y0 m, n) i2 V int mv; public: Parent() { mv = 100; } int value(), A8 b( N- _; b5 ~8 y { return mv;3 X, D7 |" @$ \) P- q* V9 v3 I6 H } };! j& [% S. G! X! ]& n class Child : public Parent {6 e) |- c2 e9 ~. ], u+ Z" j; N0 I public: int addValue(int v) { mv = mv + v; // 如何访问父类的非公有成员 } };+ h6 f# z) v% Q3 N: V* I ) |0 w! [9 J; N* x int main() { return 0;0 ]0 t6 j; s1 o" c8 A } 输出结果: root@txp-virtual-machine:/home/txp# g++ test.cpp ]/ i2 O) G4 B) [- j& v& rtest.cpp: In member function ‘int Child::addValue(int)’: test.cpp:9:9: error: ‘int Parent::mv’ is private 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; // 如何访问父类的非公有成员 ^ test.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 mv = mv + v; // 如何访问父类的非公有成员 ^6 z& z9 W, o, O: c6 r 注解:我们可以看到子类不能直接访问到父类里面的属性 2、继承中的访问级别关系
-- 修饰的成员可以被子类直接访问 代码实现 #include <iostream>#include <string> using namespace std;4 [, S, l8 Z& Y" V1 h3 Q; D9 H class Parent: l4 S! B4 D( Y% Z, R% W { protected:: J1 ~2 F) P( m# T* ? int mv;- p! ~" j1 k( Q R' q- @& T public: Parent() {# A: \ N. F* j* N8 [# X mv = 100;# f) |& ?+ a: x+ X* }1 D/ K8 d4 u } : U# Z) G$ |5 c: i8 L1 W2 w int value() {: U9 [# J# m# U6 K% T return mv; }# L6 Y- ?6 c- _/ A! a1 A }; class Child : public Parent {' J9 @* E+ F; s; _1 J+ f" P public: int addValue(int v) { mv = mv + v; } };) V% j) o$ c+ R" z0 K/ `: C int main()8 g( S$ s) y8 T { Parent p;/ R7 ?% D2 t0 C5 ]7 {3 U* \- h3 a6 s cout << "p.mv = " << p.value() << endl; p.mv = 1000; // error2 n! v0 w1 s) P& |/ C( U . C0 n* T ^6 r Child c; + n" z. v" L e/ i/ ~4 p' t cout << "c.mv = " << c.value() << endl; 1 J% `9 O- H6 o& N c.addValue(50); 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 return 0; }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 utest.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; ^ test.cpp:37:8: error: within this context p.mv = 1000; // error, p/ g8 H9 X$ A; f1 U* _ ^ test.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 ^ test.cpp:47:7: error: within this context F' _ v1 s- ^4 ] c.mv = 10000; // error& ^& |" r; N( s9 y5 k' h 注解:这里我们把父类的属性private修改成protect,这里我们注意到在子类里面的方法中是可以使用父类中的属性mv了,只不过在int main()函数中,使用父类和子类定义的对象,均不可以对父类中的属性mv进行访问,这一点要注意。 3、为什么面向对象中需要protect? 我们还是用生活中的例子来理解,每个人的个人隐私,是不能泄露的,也就是我们c++中的private关键字;而你身上穿的衣服,每个人都可以知道,也就是c++中的public关键字;最后我们的protect关键字,为啥c++中会需要它,我想还是跟生活中有关(所以说,面向对象的编程,非常贴近生活),比如说,家庭开会,有些事情就不能让外人知道,但是自己家人就可以知道,所以这跟protect关键字的用法非常像,也就是说,protect关键鉴于private和public之间。 4、定义类时访问级别的选择:
注解:从图中我们可以发现,当有发生继承关系时,就考虑使用protect关键字 5、组合和继承的综合运用
说明:Object这个类是被用来继承的;Line和Point两个类进行组合。 代码示例: #include <iostream>#include <string> #include <sstream> using namespace std; . \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; string mInfo;* N, t- T. }2 R% @% |; L3 M j& H) f public: Object() {% 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() { z) J( G) {) G) ?4 { F return mName; }$ 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; } };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: int mX; 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; 4 O2 h% l/ B1 R6 S: y: P mX = x;1 W* ~- q; c3 u, W, S mY = y; mName = "Point"; s << "P(" << mX << ", " << mY << ")"; - O+ N* \) s, ?9 r5 }/ w mInfo = s.str(); }4 s" g6 Q" {% `0 Q9 c7 C) Q int x() { return mX; } int y() { s+ z& d6 C, W! {2 I/ r return mY; m4 u9 ]1 T- Y9 f8 b }: z2 l) I) |) G }; class Line : public Object { private:; U" `6 S- G3 h" L. l; A2 | Point mP1; Point mP2;4 r% V4 S+ L7 y public: Line(Point p1, Point p2)9 w+ c- l: a, L* V; v$ Y$ j {5 Q. I( m" x) I: s ostringstream s; ' |- ?% 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"; 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() { 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 { return mP2; } };- y- K3 A' }0 [- ]$ x8 g8 l# n & F/ e; O B6 ~6 e1 m$ @" ? int main() { * S# j% h0 L# V% _ Object o; Point p(1, 2); Point pn(5, 6);. l, I+ Y L4 J# M Line l(p, pn);+ z; x# H# j+ N0 I( }( @$ R2 p cout << o.name() << endl; cout << o.info() << endl; ! X+ j9 J) E2 W; h8 @* ]6 v- n cout << endl;( Z1 e% `4 m* ]8 T/ D4 A cout << p.name() << endl; D* f+ U! G) w# [+ G cout << p.info() << endl; + L$ O4 d0 C; S6 Z cout << endl;/ g( E" v3 Q! ]% e$ ^( { ; p) T& _. I4 D# h cout << l.name() << endl; cout << l.info() << endl; $ }1 H/ W4 ?+ `0 k) N return 0; } 输出结果: root@txp-virtual-machine:/home/txp# ./a.outObject8 ^4 }: v! b: d/ F, c6 Q ! _- D/ j6 G9 x, @7 x, | Point P(1, 2) 3 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 二、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版