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

c++ ——三种继承方式

[复制链接]
gaosmile 发布时间:2020-8-21 10:07
在上一篇文章中我们已经接触到了protect这个关键字的作用了,今天我们继续深入继承的深入学习。
一、三种继承方式:
1、从问题引出主题:
(1)冒号(表示继承关系,Parent表示被继承的类,public的意义是什么?
class Parent
$ F8 N8 ~$ U1 `7 C+ r% A. z{2 m% u) P6 d. }% h) \) p
5 V9 S/ M* O. M9 `: L# J
};
( V1 o! V3 j/ S+ e/ W2 g' c2 m; V' o% U* {; D
class Child : public Parent( r% R/ O6 a8 W+ C
{, r: Z! ?3 F9 u9 T9 K2 M+ l% f

, U! s5 Y/ u* ]( x. [4 T6 V2 [( N& m; s1 _& K; N. {! p
}
+ s/ d3 h* u; T# H* x1 i. a
(2)是否可以将继承语句中的public换成protected或者说private,因为写代码的时候,你肯定会有这样的好奇心;同时如果可以这样写的话,那么,这样与public继承又有什么区别呢?咋们还是通过实际代码来理解:
#include <iostream>
8 s* o; p7 e. f% ?#include <string>
( T: p) W( d! E4 Z; F+ [) g; |$ f# ]
using namespace std;
0 Q5 n- ^1 T3 l' `+ i! d$ d- C
) {5 V+ O9 `! C" Q9 hclass Parent
4 @6 X7 m+ w( d- @) ]8 t" g" Z  T7 X{9 Y( q- _- `: F7 H- l4 e
};, R. O( N, j: q$ ]$ q
$ E# @! ?, |. _7 X+ E; J5 |3 o9 U
class Child_A : public Parent
9 G5 U" i' @* n; y$ Z4 G( `{
3 S4 H& f6 R) N& N' }};
4 g+ `- @# n  G) L+ N$ s/ K! x/ a; N
9 @5 ?; _! r# V5 V. qclass Child_B : protected Parent9 M7 ?% n7 x+ L' R" E
{
' i6 g9 g- j1 v( r1 d4 p};
+ t6 X0 @& G$ h; v- X: x9 k0 d2 B: ]7 Y/ N( Q
class Child_C : private Parent
' E  B9 O2 s! }8 T0 a/ W, a{
0 s( {' x) ~4 |, S) g( D+ h};+ n- W& {/ w3 ?$ g! }; @, {; p/ n& U+ ]1 y
- w4 J( X/ x- a: L; ^! i; y
int main(); b! M$ m+ R- \: p' E. J1 j
{   0 @5 w, B& c6 `7 Q0 r
    return 0;
2 M& _8 p  _' G+ U& C3 u' j& M}
8 N/ s+ m* `  X1 i! Q, ^4 B6 Q4 w% N( O. x3 P7 y2 I
试试看,能否编译通过:
root@txp-virtual-machine:/home/txp# vim test.cpp
( ~5 D+ m$ _' N! n# W3 c- Y  H- troot@txp-virtual-machine:/home/txp# g++ test.cpp/ u! t/ ?; w& ]/ |5 O, K( l; {
root@txp-virtual-machine:/home/txp#
! A4 a4 X, v/ Y4 J  V( X! z7 n6 A( D& n& o9 c
! U& p- }2 L4 q( F! T
注解:通过编译我们发现,完全没有毛病。
2、c++中支持三种不同的基础方式
  • public继承:父类成员在子类中保持原有访问级别
  • private继承:父类成员在子类中变为私用成员
  • protected继承:父类中的公有成员变为保护成员,其它成员保持不变。
    / z* r( r9 m! j5 U/ c
微信图片_20200821100627.png
继承成员的访问属性:
=Max{继承方式,父类成员访问属性}
注意:c++中的默认继承方式为private
代码实践:
#include <iostream>( r& i, }) W: L/ }  m; O: O* o
#include <string>
7 C# s' j  s3 d  u( C6 h; ^  @2 u* y$ i: K8 R9 k. `
using namespace std;/ e* W, y" Z# U

; p7 N) b: d" j7 j% @" o, wclass Parent& P# I3 w, c6 o$ g- [  |% p
{
: c& q) D, d) p5 S) E! Q  L0 A3 gprotected:
; c0 w* ?9 X# G0 ?9 a& N5 ~    int m_a;
) J8 a/ u$ b# Cprotected:# Q  X* ~" p3 K0 K9 M% ^
    int m_b;
) R1 O6 f5 T. k2 K3 o6 x) hpublic:* e! q" ~$ k; E$ D* `# S9 m
    int m_c;
2 J" W& X2 c+ t8 l, D    ) q( o, y. d# w7 h- N
    void set(int a, int b, int c)# ?% y8 q2 u6 C* {2 u- Y
    {
! L7 J4 t' p; l" F        m_a = a;
; G: _6 E: e5 ^$ U        m_b = b;
3 W+ _$ E+ F9 C$ w9 b        m_c = c;
6 v5 u8 h2 c5 k9 |. Y6 t9 }    }' G! V9 p  `/ U7 Y  C
};# O3 A7 {1 o$ w" a
1 K! u* v" K+ `
class Child_A : public Parent7 W0 K2 X# q. L2 i
{
& D6 }! S+ S- D( m2 ?public:
8 Y& i  q# w# X6 Z2 z    void print()
  ^0 F2 `$ V2 K* [( R" `    {
5 s3 I0 @! ?& o        cout << "m_a" << m_a << endl;/ N! g+ r+ A! K2 a+ x% B
        cout << "m_b" << m_b << endl;. M& ?- ^( H. _' u" o* _
        cout << "m_c" << m_c << endl;
7 Y& f. s; N  h* F" F    }
2 Y1 W) c6 I4 T0 A* @};2 k$ K" }+ g- Y2 g: T) w' c/ [
. b/ U# M% f0 ]+ Z
class Child_B : protected Parent2 _2 _) G0 ~3 v3 V/ N
{' q  v# N, \5 @/ ]' t; \
public:. g9 R3 P  w/ t! [% [" x. u) d( M
    void print()
* Q+ \) i  W" {+ d, ]9 S' O    {0 t0 v/ T0 G; s7 g: T; y
        cout << "m_a" << m_a << endl;$ S) A  v( c% ?& h
        cout << "m_b" << m_b << endl;
6 ]: {2 I7 F, c" g        cout << "m_c" << m_c << endl;
- K3 ?. L+ l2 i7 l' ^( ?% v% v    }
5 }: q" R% h- H) N$ v. A};
' w( U/ C0 e, H
; B2 [5 G5 e$ }7 \1 |2 W& s2 j2 \class Child_C : private Parent
3 U: v( G: w  A7 X3 ?{2 q  u8 z4 d: e5 u# z" d+ B3 q
public:
  L9 x, L- `. e/ H6 T    void print()
" ^0 }# m+ ~  V) _    {
* z2 k3 C* y: t! B; p: J        cout << "m_a" << m_a << endl;
2 h$ @( H& R7 E3 x$ T3 A4 r- Q, f        cout << "m_b" << m_b << endl;
7 L# e$ D! J  s% G1 W3 w% p( }        cout << "m_c" << m_c << endl;* X3 ^2 e) p6 h3 R
    }2 R  u% p8 y  W7 t: k$ z
};0 X) I9 {& Z. ^) g: i9 h9 j

6 x$ U# F  X$ {# l' H- x8 J' Cint main()5 }9 |+ d& T1 p8 H5 \( x& R  Q; t
{   
" k+ i/ J1 K# d9 |  a6 T( c    Child_A a;3 v3 \. }4 c. [; ~4 S
    Child_B b;  C) T/ E% E' }  p. t6 D8 U
    Child_C c;
+ C3 n% S. ~5 ], s# E& e8 v: H   
: R1 u( V+ U1 q# r' p    a.m_c = 100;1 o$ z9 _6 D' [4 W0 J
    // b.m_c = 100;    // Child_B 保护继承自 Parent, 所以所有的 public 成员全部变成了 protected 成员, 因此外界无法访问
, {. x* Y* {, @" l) D& L7 m7 [    // c.m_c = 100;    // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问" Y/ m" S( X2 q$ I& q( t8 g. v
    7 m1 j/ z! Z7 J9 k5 I+ v
    a.set(1, 1, 1);
( @* ]+ J4 n$ D* q0 o2 H( d3 H    // b.set(2, 2, 2);
# x% g5 T6 [* J/ g8 Y  g% N    // c.set(3, 3, 3);* y. J8 m) A" E" {1 r
   
8 }; B  N' j/ W8 w2 p3 g    a.print();1 ^3 ]% U7 U8 n* x/ A& ^. V4 Q8 i
    b.print();
0 a  ^. P; @+ v7 R    c.print();
# f$ L' R5 ]( ]8 W4 ]! l4 Q7 T2 z    ' Z& u2 e& l$ c& q
    return 0;' P0 t8 v; J  R# D8 ?3 r
}( U# k* M0 m  `, v# L+ m. I/ [
. p' [# w5 E6 c
输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
! a* u  J% p9 u* w" t' ^/ C2 Bm_a12 _/ p% ~" c$ [/ E2 _$ m1 e$ R7 ~+ C
m_b1
' I, c9 Z- q! i6 ^9 q5 n( Xm_c1* ?. \5 y) M& s$ k
m_a4197200
4 M! O+ ~* H/ r, J$ v) o! Lm_b0
' m# @; }' |! H" T5 E! Hm_c4196272
5 ]) i9 R, {6 g& z! }6 f. ]m_a-903133344
" w& n; w. B" y( ^m_b32766
3 h1 p" X( v" n- Y4 {7 Rm_c0
+ [9 u* r6 M, e" N6 I' q5 I$ t1 E7 W+ \/ [
代码实践二:
#include <iostream>
; j  J3 k7 y3 M/ E% F8 {; B5 z( v#include <string>! P9 A9 R2 y/ P- ]
+ y0 \. s2 r9 F0 L/ i7 }
using namespace std;/ d7 i. D) t% X6 f9 i9 a& x

; i  s4 J' i1 |- F) yclass Parent; j: P* |" j  g/ }4 F
{* A. U: t4 F: k6 C2 j
protected:
! G; e& M3 l4 V, v  o) N) H( F    int m_a;
+ I  N) b  z, W3 `2 kprotected:+ w( J9 p8 p5 c; t# M' v
    int m_b;
' B+ R' q4 a8 t5 N$ p+ s: ypublic:% D! b9 G0 ?' t! _% g  l+ Z
    int m_c;
3 T  s: c  C" T; O( r    $ Q6 O6 o3 s+ x, m" @7 X0 E2 U
    void set(int a, int b, int c)  d0 l* t: t. I& f+ a  z. T
    {
+ v! ]% A# x6 U2 ^. e4 W9 Q7 q        m_a = a;
- v) g* |3 \& f9 Q( s. X        m_b = b;
0 V, S. c( ]% }! a9 b9 D2 V4 e0 o        m_c = c;+ W5 q9 [' `& Q( J; y, D4 `/ L& @/ U
    }! R! b4 s- y2 t
};
) |  Z  ]8 R$ A+ |& y4 J. i8 ~4 L+ B9 Q2 q& u$ w8 Z
class Child_A : public Parent5 S& I& X% O2 ?6 |. O$ }; ^
{
$ }( O3 k% X$ a% h8 Z2 {public:
0 d( c" t: v$ ]3 `, T6 G; B    void print()1 `% _2 S7 n" {
    {5 _/ b" d: G; I' J4 W
        cout << "m_a" << m_a << endl;) o5 J# ]/ V6 P3 T" I
        cout << "m_b" << m_b << endl;9 Z1 Y: u7 b3 W$ j) w. D* ~
        cout << "m_c" << m_c << endl;% y8 k/ m& [. o! n4 l' o9 R
    }6 K* W7 @* c" t2 `+ x
};0 y9 ?, Y3 \% f* y  Z! B' }( N
8 u2 c/ ~3 Q) M/ ~0 I! y* K
class Child_B : protected Parent$ M* r6 \+ w& L% e4 Q
{
' F% p9 ~! H$ a1 a1 J# U/ {% ypublic:
8 z# @4 R# B# R% N    void print()' v: v6 Q# w2 _# R, @1 w; ]
    {6 A+ ]6 y; N$ M$ l3 b3 |1 Q
        cout << "m_a" << m_a << endl;- W# h8 L8 k) X
        cout << "m_b" << m_b << endl;
, b! q: E6 O7 k8 ?9 h* h        cout << "m_c" << m_c << endl;1 y5 t1 ~7 R+ |- S8 Y& }9 t
    }& D1 M. s. {3 v6 S% @; K
};, a  x- E0 f- u
' s9 B6 V" R$ i8 n2 y5 Q
class Child_C : private Parent4 |0 [' R0 T1 E/ w) @* K% G
{* |$ T- G$ L7 \
public:
( U( _7 Z' @7 W; Q' o    void print()
2 }! I+ v( J9 u+ ]. O- {2 [4 E* w    {
; e1 n8 l, b- o9 T) b        cout << "m_a" << m_a << endl;' S8 n8 q( n$ s8 C* O2 ?) ?' l% ~8 J" E
        cout << "m_b" << m_b << endl;
5 V3 S- U0 y* B. c; ?        cout << "m_c" << m_c << endl;, r1 V5 k) q2 i2 Q- f( h
    }
+ ?' [0 {( B) T+ S( Z* f+ q% A};5 }5 J# ~* X2 Q4 t6 E  Q! W7 X

$ g' ?" s! S7 g" `; s- X) D( e) p) Gint main()0 Y2 v# @$ i+ X# V6 @" I* X
{   5 a# J9 |1 E2 z8 I9 P2 e
    Child_A a;, E2 ~/ d8 [' N! K% q
    Child_B b;
4 N: l! n# G! y) f# K    Child_C c;
! }/ w5 b% F' W+ F   
' E' {" D( q4 x+ L# x. }7 N    a.m_c = 100;
* q; ]# P- f6 F3 _% E6 _  ~& |: o    b.m_c = 100;    // Child_B 保护继承自 Parent, 所以所有的 public 成员全部变成了 protected 成员, 因此外界无法访问5 L' \0 J8 u" g: z! _) q; ~" ?' g
    c.m_c = 100;    // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问
- }) v$ f" |; G# ]) d% A   
3 ]# }8 m# O1 \; G    a.set(1, 1, 1);
# h8 s: Z. N' V% t/ Q# p    b.set(2, 2, 2);8 i2 d5 z, [! c) n9 L% T
    c.set(3, 3, 3);
# ~7 C7 y( U8 ?- D+ }    % N% K0 a' ]* Y" [- _
    a.print();& B! I0 y; J+ ^: }2 j' U
    b.print();/ K2 Z1 V) a3 X9 `' I6 \7 p1 C2 \
    c.print();
; ^! q5 @" \" B. D9 e    6 h. C) s6 t+ f/ F6 B
    return 0;2 S# S0 q& q& G/ b9 q: M
}
1 M: o9 k! I% G) `, G. e& W8 g( W8 b$ k
输出结果:
root@txp-virtual-machine:/home/txp# g++ test.cpp
! p& v- J) C5 a! ]4 i! _, Ptest.cpp: In function ‘int main()’:/ r) Z! t7 G8 q0 F$ e( ?
test.cpp:13:9: error: ‘int Parent::m_c’ is inaccessible
% Z) d  {$ Q0 ]# x     int m_c;
/ Z  R8 s9 o) u0 h. N! K7 |         ^2 m  d4 t& ~  n. q
test.cpp:63:7: error: within this context
6 K) n1 E; {; |- K, v     b.m_c = 100;    // Child_B 保护继承自 Parent, 所以所有的 public 成员全部变成了 protected 成员, 因此外界无法访问
+ I, Y( u" C) \' i; ^2 Q       ^
& \- R- d# l7 I) q1 [  S( ?! j& D# etest.cpp:13:9: error: ‘int Parent::m_c’ is inaccessible
. ]: C4 T$ y9 a1 n' r     int m_c;) }! A/ |& O; |2 V5 g0 E
         ^! L& x, F2 X0 H! l  [+ w
test.cpp:64:7: error: within this context
: R2 A$ ~9 l3 A: G     c.m_c = 100;    // Child_C 私有继承自 Parent, 所以所有的成员全部变成了 private 成员, 因此外界无法访问1 n- ?- M, }& O7 q+ n% _
       ^
1 g! E5 C; P! g1 ptest.cpp:15:10: error: ‘void Parent::set(int, int, int)’ is inaccessible* ^& f" P$ H1 J! Q7 h2 I
     void set(int a, int b, int c)
( n6 {& h  d7 d4 q          ^; d# i9 c2 L7 v) t6 K! s
test.cpp:67:18: error: within this context+ W2 R0 `! ^' A8 p& c- r
     b.set(2, 2, 2);
3 n" W3 t1 F" E) r# u- M) _                  ^
) `5 V  Q3 X5 ]) Gtest.cpp:67:18: error: ‘Parent’ is not an accessible base of ‘Child_B’4 y: G+ c4 i8 u" {  l9 c
test.cpp:15:10: error: ‘void Parent::set(int, int, int)’ is inaccessible! B; I5 K/ x: [! ^7 @; [7 M' g
     void set(int a, int b, int c)
- Y2 G4 y5 I  |8 G          ^
0 F& Z' L1 t" V( |test.cpp:68:18: error: within this context! p7 l* O# e: ]; `2 `! z
     c.set(3, 3, 3);
$ ?' B& M4 c% @, [0 R! H. T/ l                  ^
9 @! O) W0 N2 Q% b: P. d$ D' W/ M* N2 mtest.cpp:68:18: error: ‘Parent’ is not an accessible base of ‘Child_C’
6 q4 e+ F' ~2 U4 n
* Y. @: P$ K3 x& L( ~* B3 Q
注解:当子类定义的对象,如果继承关系不是public,那么子类定义的对象,就无法访问父类中的属性和方法了。
3、遗憾的事实
  • 一般而言,c++工程项目中只使用public继承
  • c++的派生语言只支持一种继承方式(public继承)
  • protected和private继承带来的复杂性远大于实用性
    ; M3 |6 U4 S3 [4 I/ Q
二、总结
  • c++中支持3种不同的继承方式
  • 继承方式直接影响父类成员在子类中的访问属性
  • 一般而言,工程中只使用public的继承方式
  • c++的派生语言中支持public继承方式
    3 e8 y0 X* L$ R7 |, ?: N
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。
8 J9 [) i1 W, m' P, s3 t) o/ M
赞 收藏 1 评论0 发布时间:2020-8-21 10:07

举报

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