|
一、父子之间的冲突: 1、思考 子类中是否可以定义父类中的同名成员? 如果可以的话,那么该怎样区分呢? 如果不可以的话,那么又是为啥呢? 代码实践: #include <iostream>#include <string>. O( r6 j0 g: _6 B) |/ |0 i . n3 D. ^: l# f5 d, `& Z1 u using namespace std;& \( M, k. K$ P3 F( C8 [) E, ^. S/ ` 7 d; O+ ]5 I9 h* C class Parent { public:( s( @6 g" ]0 {+ ^1 z int mi; }; 9 c z0 V8 U0 r& I$ ^ class Child : public Parent1 k, f3 Q4 y0 d! y5 L {/ Z0 x- ^* h4 q& z. s. P public:. N `" ~& @! I int mi;: p% i3 Q1 h) n* _4 t, Y };0 z. p0 V* E+ [: l 2 ]8 S/ y0 v. F1 P) d4 p4 b4 [ int main()7 {0 c1 {9 [4 [! G3 E; i { Child c;/ } d- O& M$ u: m' e " [- w! p0 ?5 M7 V c.mi = 100; // mi 究竟是子类自定义的,还是从父类继承得到的?0 {4 t- f1 A/ U return 0;: p. C* A* b3 d9 s8 ` }0 |3 }% }/ p+ Y, w4 r" j7 A 代码是否可以编译通过,我们来看一下编译器编译的结果: root@txp-virtual-machine:/home/txp# g++ test.cpproot@txp-virtual-machine:/home/txp# 4 H: r/ a7 [7 F) L : b" R0 o" `$ E* O 什么情况,居然可以编译通过,但是你从肉眼看,你看出到底是父类mi还是子类的mi呢,显然我们不能够去瞎猜,那么接下来我们来学习里面的真理! 2、父子之间冲突的规则:
c.mi = 100; //子类中的mi/ U' Y+ L9 g* d0 I: f6 D ^ c.Parent::mi = 1000; // 父类中的mi, I0 o% ~( \/ `* w! l 代码实践: #include <iostream>#include <string>! b; l/ E4 R) u& x7 ?! p using namespace std; namespace A { int g_i = 0;* s" m* r/ @% c/ ^( G3 ?5 G0 G2 z } $ M, r9 y' b& L$ ^% V5 m namespace B4 n8 @( R C7 G7 v. s* V { int g_i = 1;// 同名的全局变量,但是位于两个不同的命名空间; } class Parent { public:4 M6 M4 v* d$ A2 y int mi;% \ S7 I$ t5 q Parent() { cout << " arent() : " << "&mi = " << &mi << endl;# s( M: k$ [5 k: E}$ z H& F) C# b7 [5 r4 ^ };, `; B! t; m* O1 V- W " O$ n! W( d6 I6 X) W7 B class Child : public Parent { public:3 l3 |) o: b" X7 }: F- f/ R7 V int mi; Child()7 ]$ h" o/ u& g: m' m5 ]) L {8 y; Z2 E, b; E8 | cout << "Child() : " << "&mi = " << &mi << endl;3 y* [: |' D3 c8 d' ]: G }5 ~7 S8 I8 q O9 _ `4 p }; ' W, Y+ F2 {% P7 c int main() { Child c; c.mi = 100; * `& V* i; u. {" j8 T% M0 {4 I' z ! b3 n2 F7 l. l5 A! ?( v c.Parent::mi = 1000; cout << "&c.mi = " << &c.mi << endl; cout << "c.mi = " << c.mi << endl;; t# O* C' |% r : {+ P1 ?/ \: q5 w6 y cout << "&c.Parent::mi = " << &c.Parent::mi << endl;" [5 E9 f1 h# _$ X: T* X1 J cout << "c.Parent::mi = " << c.Parent::mi << endl;& o" l- c% ^6 p& ]6 N! { return 0;! g2 g' m9 k( e& K7 g- T }) L5 M M5 L8 W; @' _9 a! L 输出结果: root@txp-virtual-machine:/home/txp# g++ test.cpp, Q% j+ Q N/ L0 Eroot@txp-virtual-machine:/home/txp# ./a.out Parent() : &mi = 0x7ffc270e7bf0 Child() : &mi = 0x7ffc270e7bf4' A# O' T$ H4 ^ &c.mi = 0x7ffc270e7bf4 c.mi = 100 &c.Parent::mi = 0x7ffc270e7bf01 T0 H" Y: I3 J c.Parent::mi = 1000 6 o' Q; ]. t0 q6 V% p A0 T 3、回顾重载: (1)类中的成员函数可以进行重载
(2)子类中定义的函数是否能够重载父类中的同名函数呢? 代码实践: #include <iostream>#include <string>" q G1 a3 @$ i5 U 7 T9 d1 h i4 N3 D using namespace std;/ D# R1 T- U( R7 h( r% [0 ?; j( Y6 j2 @ 9 ?+ i. H! {: s8 x class Parent {8 j2 Q2 t! f E1 m public:; O$ X7 J) r* f9 P P9 Y0 m1 y int mi;. I0 B# E- b0 [ void add(int v) {4 a2 _0 m$ u) ] mi += v;( k) F! x& a+ ` }) Y. d+ L4 r% Z 3 @) H" r$ T/ w; Y3 |% E5 q void add(int a, int b)! u/ Z2 ^1 f! g9 z' q {. T) U! T3 E% f/ E; g mi += (a + b);0 q9 `7 J- j1 I6 O8 H } }; class Child : public Parent {5 P H- X0 [) p. U8 Y; l public:- q- u) O8 x( C a4 p int mi; $ C2 R6 G2 S! _, \4 S) E void add(int v) { mi += v; } 3 {% d6 e9 C6 g: V: H void add(int a, int b)( k7 ?, ^4 R, B$ x {3 ]% F" ?8 R9 u! h# G mi += (a + b);# A- i" {% p# J' p" z- d, `. i6 j } B$ R5 O/ g( d- ^# T$ e void add(int x, int y, int z) {0 w/ X9 h8 c5 L2 Q) v+ c/ m M mi += (x + y + z); } }; ' @; x, v8 [! w2 j int main() { Child c;; ]/ x a, n" z% W1 b/ N: N) K 3 k+ [! x. M, S% r8 T c.mi = 100; c.Parent::mi = 1000; cout << "c.mi = " << c.mi << endl; cout << "c.Parent::mi = " << c.Parent::mi << endl;: W4 `3 L' z( U9 h- a ! d' o& x" h7 O A7 m. a9 O c.add(1); c.add(2, 3); c.add(4, 5, 6); * A) R* w. R2 h2 L( g cout << "c.mi = " << c.mi << endl; ; ` ~/ Z3 V& o3 C cout << "c.Parent::mi = " << c.Parent::mi << endl; * e) U, c4 j6 Z/ D return 0;2 b6 R, f! U6 y I9 V* M, O1 P' r } 结果输出: root@txp-virtual-machine:/home/txp# g++ test.cpproot@txp-virtual-machine:/home/txp# ./a.out c.mi = 100 c.Parent::mi = 1000 c.mi = 121 c.Parent::mi = 1000 注解:从实验观察来看,函数重名和成员重名的作用一样,子类会覆盖父类的。 为了更加说明这点,我们再来看一个示例: #include <iostream>! m, T- b# [$ k' N#include <string> 2 r8 S9 B- }# h using namespace std; z8 ~. a7 t0 N6 }- Q# t9 c) }6 T ) ~ [* |. P5 j/ g6 _ class Parent! _9 i2 u5 e; T8 w& x {& g5 j" g& |8 p* q6 U public: int mi;7 a) f9 p% g- [; t: C( D - p- }7 u! x. \# a4 C9 ^! J; ? void add(int v) { mi += v;: r+ T% Y. [; B2 H# U. F9 q } $ A# R0 N+ }/ k9 v void add(int a, int b)# [- O6 S4 i. i+ v { mi += (a + b);- Q z% ~0 |* B }8 { b' }& [! F5 X" E) o; W }; class Child : public Parent { public:( \9 W6 s# j9 l! i# u' r7 I& g int mi;3 Y q8 e; q. G void add(int x, int y, int z)' |, J4 L+ [+ e {1 f8 |8 f1 W5 ?0 I% B5 ^3 n mi += (x + y + z); }9 M% i( S( j/ ?& m. w' j };* w1 _" F1 T- c5 S 2 d) Z- ~) Q6 K8 S int main(): f0 T5 m0 E8 ~$ o) W3 n. M { Child c; " D4 ^5 w) M/ ]. \ c.mi = 100; + R/ Z4 e2 {) b4 |* s5 R - ]: S, |+ t0 g) k. o! X) w( P+ z) P c.Parent::mi = 1000;8 P6 `6 B; l! i' x 2 {, n+ J8 O, P5 l7 e cout << "c.mi = " << c.mi << endl; + J6 L' f4 H+ t4 F" l+ v cout << "c.Parent::mi = " << c.Parent::mi << endl;. k6 r5 L8 P: `, J- h k( Q* D2 X : h3 ]9 _( t. U# x c.add(1);1 O) X: V8 v) t* F" C! _& @2 V1 |5 W; ? c.add(2, 3);, |. W M f9 A: M+ U c.add(4, 5, 6); 0 t5 _" v! S& g$ u& t+ Z3 q cout << "c.mi = " << c.mi << endl;4 W2 V: U/ ^* v+ L 2 F7 w% l: Z% w3 T cout << "c.Parent::mi = " << c.Parent::mi << endl; return 0; }1 n9 u# t( ?2 w1 s 编译结果: root@txp-virtual-machine:/home/txp# g++ test.cpp; }& q; h- g; z: Xtest.cpp: In function ‘int main()’: test.cpp:47:12: error: no matching function for call to ‘Child::add(int)’ c.add(1); ^ test.cpp:47:12: note: candidate is:' p0 [! l) y5 X$ T, D3 @ test.cpp:29:10: note: void Child::add(int, int, int)4 S# ~! H. `" p void add(int x, int y, int z)5 a* H( a* v; Y! s0 L: U ^ test.cpp:29:10: note: candidate expects 3 arguments, 1 provided6 Y- ^" K/ k7 Q2 k4 m. D test.cpp:48:15: error: no matching function for call to ‘Child::add(int, int)’$ y E; y1 _: D \2 c c.add(2, 3);" B5 V; ^5 H, C1 Z% [0 ~& S ^* f4 w9 \, R6 `7 ]3 R4 Q" S3 m/ f test.cpp:48:15: note: candidate is:( [+ c" \+ Q- O7 m test.cpp:29:10: note: void Child::add(int, int, int); H$ n a n0 }4 Y void add(int x, int y, int z) ^ test.cpp:29:10: note: candidate expects 3 arguments, 2 provided , m- A7 S3 ]9 w0 G+ i0 L 注解:显示匹配不到add(int)和add(int,int)这两个函数 解决方案,就是利用作用域符分辨符解决问题: #include <iostream>; a0 N- K" z/ ?/ o+ m5 n% P8 z#include <string>( \* P# @+ |3 ?' ]5 t S: v using namespace std; class Parent { public: int mi; 0 i0 K3 p) [, K; P void add(int v) { mi += v; } void add(int a, int b)# u6 K* D k% w {8 Z6 l9 C; ]! Z9 ]# U0 i mi += (a + b);( S8 J* |9 {% c: s+ P9 j$ @ } };# z, |0 R2 T, b) z3 v4 O2 z. e. t: C 9 L. Q X9 b7 p6 [! s e( | class Child : public Parent* k0 f& h+ w0 k9 [7 g9 n8 f {3 ~# b% I# B0 R) o+ z, j8 j! r! x; p public: int mi; , X* V: w6 p! {6 r) _. {9 H void add(int x, int y, int z) ~3 W, e' V' ]) f2 F1 a9 [5 A {5 A$ I* b" o( `" @ mi += (x + y + z); T! f$ {9 ~3 c* s/ I# S4 c/ c) n } }; int main()5 `4 q% w% l D" S6 U {; H% M! o8 x" y Child c;. Z! T7 r$ A p: m c.mi = 100; Q' Y& K4 w/ v1 K+ p * l: E* ]( f) F8 G5 t* B& @ c.Parent::mi = 1000; cout << "c.mi = " << c.mi << endl;4 [" @( `9 x B) v C5 a cout << "c.Parent::mi = " << c.Parent::mi << endl; c.Parent::add(1); c.Parent::add(2, 3);: J( |3 e8 | I3 M) s) ~ c.add(4, 5, 6); 0 g) W S9 ?. [! c0 Y& R( c cout << "c.mi = " << c.mi << endl; cout << "c.Parent::mi = " << c.Parent::mi << endl; return 0;& B& A6 B" L6 e; C5 w. k8 V+ y }( }8 l0 q9 |, F6 b' V- y% R) T [- G' o/ P0 s3 k# [6 _ 输出结果: root@txp-virtual-machine:/home/txp# ./a.out# l( B+ A4 ~/ |" b7 vc.mi = 100- y3 ~: M& |& g5 q3 L c.Parent::mi = 1000, K( R& A: c; ?9 L- i7 x* a c.mi = 115% ~; t$ A1 o$ d6 T c.Parent::mi = 10062 L/ b" p) b3 B 4、小结:
二、总结
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版