|
在我们前面学习过类中的构造函数,以及析构函数,那么自然而然,在继承关系中,必然是存在着析构和构造着。 一、子类对象的构造 1、问题的引出 如何初始化父类成员? 父类构造函数和子类构造函数有什么关系? 2、子类中的构造函数怎样初始化父类成员:
--必须对继承而来的成员进行初始化,那么怎样初始化呢?这里有两种方式: -直接通过初始化列表或者赋值的方式进行初始化 -调用父类构造函数进行初始化 3、父类构造函数在子类中的调用方式
-适用于无参构造函数和使用默认参数的构造函数
-通过初始化列表进行调用 -适用于所有父类构造函数 实践代码模板: class Child :public Parent{! ~ a$ Q* g o. ^7 ~8 K public:( Q9 c3 y; x* W5 H% Y Child()//隐式调用 { cout<< "Child()" <<endl;0 b! j5 k& }" \9 v* n7 J- f/ } } Child(string s) :Parent("Parent to Parent")3 a5 n0 \: t6 i5 A { cout<<"Child()"<<s<<endl; } }; F2 d- ]9 c, ?8 V6 F: I; | 代码实践: #include <iostream>#include <string> using namespace std;, T* { q7 W' \1 w+ v6 |: q class Parent {: Z7 [( H" @2 H& w2 j public: Parent()/ \2 [+ D9 v- R4 ?# g" ]/ t" t { cout << "Parent()" << endl; }+ V. E# j, |) f% f7 E6 O4 l Parent(string s) {* d- I4 M# C; B6 D. R cout << "Parent(string s) : " << s << endl; }2 ?/ A% j% Z% e: V/ z& n1 C: F& m };! D( ]3 t: l3 f0 |' ^; t3 i class Child : public Parent" T: z" G" a! T8 i0 ? { public: Child()2 t* F, n1 I1 N3 Z: v { cout << "Child()" << endl; }9 K+ s. O) {# I- v Child(string s) : Parent(s) {- ~% Q2 I1 A4 ?& g; a4 v' x0 N cout << "Child(string s) : " << s << endl; } }; int main() { Child c; Child cc("cc");* j' g# x6 S% F6 g a, \ + U( q+ j: \1 i7 t# Y. s" i4 L return 0;- N& Z3 U3 }" _; A1 |2 c3 X# A }8 e9 F# k5 s( l X " m, g3 z+ B2 K: `5 C* Q 输出结果: root@txp-virtual-machine:/home/txp# ./a.out; ^ Z4 `+ s4 Y% BParent() Child() Parent(string s) : cc Child(string s) : cc 0 C6 ?1 s7 R e9 o$ ~; Y6 U. M; E 注解:通过上面的代码输出结果,我们可以发现,子类定义的对象如果没有没有传参,就隐式调用父类的构造函数;当然上面也使用了显示调用,通过初始列表的就可以看出。 4、构造规则
5、对象创建时构造函数的调用顺序
总结:先父母,后客人,再自己 代码实践: #include <iostream>. o# z6 c5 j. y" K/ U#include <string> : I0 R9 r' n! o- P1 N using namespace std; , I4 t6 _7 \: F; G; }; K5 G class Object4 i- l. K: d) u2 W {3 _# L" t% j# @: }! |( [ public: Object(string s)3 f! [+ W# V! w3 | {2 i% o- k; a5 B9 d { cout << "Object(string s) : " << s << endl; }: K& w+ n, Y4 A) Y }; , ]. z0 I6 }; d/ M class Parent : public Object {& y& V& p% [% U/ b0 M public:5 C% a: ^' q" { Parent() : Object("Default") {& e4 w) S& V, Y cout << "Parent()" << endl;) l: {7 [, B9 E$ ? } Parent(string s) : Object(s) {+ ]" P, B+ o9 ?% K2 ] cout << "Parent(string s) : " << s << endl; } }; class Child : public Parent { Object mO1;$ e4 F# T+ c( q; b- H, n Object mO2; public: Child() : mO1("Default 1"), mO2("Default 2")2 s# f; _4 U' f: V {0 y* z3 J: `8 G4 R6 R) r. F cout << "Child()" << endl;( Z) m* N& W0 b5 ?7 b* S! H } Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")7 k0 a' A7 p2 e) V. ]3 p { cout << "Child(string s) : " << s << endl;: [0 z" l% D& e5 g2 G } };( K2 L* Z n5 O% W4 W/ |- C9 \ int main() { ' K* S$ B, q: N2 n Child cc("cc");" {/ i8 ?7 [4 A' V; o return 0; x9 q3 ~; B" `4 D4 J }+ [7 q. ]3 V' h) d" ^& W4 N' D; P7 W 输出结果: root@txp-virtual-machine:/home/txp# ./a.out0 }1 V& V6 Q+ c" dObject(string s) : cc5 \7 a) `! u8 k9 Y4 ~ Parent(string s) : cc! m0 W$ B' o% I) ~8 C) ~ Object(string s) : cc 1. }- N1 `* Q& F9 A k: E Object(string s) : cc 25 [6 ^+ m7 i, U8 d- [ Child(string s) : cc) b2 T- t6 b$ J, G/ S) Z 注解:我们可以看到,先定义了一个Child对象,然后最先访问Object带参构造函数,然后再是Parent带参构造函数(说白了就是父类先触发),然后在子类Child中又包含了组合关系(也就是客人),然后Object类中的带参构造函数,最后再触发自身的带参构造函数。 二、子类对象的析构 1、析构函数的调用顺序与构造函数相反
代码实践: #include <iostream>1 P( C6 ?8 M" d#include <string>+ A/ f1 e, S" _: x using namespace std; class Object { string ms; public: Object(string s)& w( _* ]" ~1 X# { {- h ]. x+ ]0 g8 d+ a, I cout << "Object(string s) : " << s << endl;" U! E! d) I% j, x/ \5 m ms = s; }( Y- A) ]: y0 _7 P* u3 } ~Object()* M; n/ _; ^8 J" k+ j {* t" b% a6 G1 Y# n& }; W/ ? cout << "~Object() : " << ms << endl;, E' w2 N& d/ \% g+ F }* p7 L9 m: i t( ]% R8 V/ T }; % n8 P* K/ h- M( P: H3 U4 ^" ? class Parent : public Object {9 ^& H H, @5 p) F* r& X string ms; public:( ?6 }3 |4 T7 s+ D Parent() : Object("Default") {3 t/ E' [5 o7 p, Q cout << "Parent()" << endl; ms = "Default";3 e9 K+ }0 ]4 v" k9 h9 x) l) J: | }; g9 i3 K* O7 J. T) ] Parent(string s) : Object(s)* {" K) F5 h, _. n% n. f8 O { cout << "Parent(string s) : " << s << endl;# V0 Y% ^0 a5 D1 T ms = s;6 ?! \/ Z k& F; y# D% t }3 k5 t) @- u# D& u, I" i9 o& R* C2 {3 Q: m ~Parent()% \; A# B0 e, x) B$ \% P* ^8 r1 j {1 @/ ~8 |7 T& F* }6 v* D3 }' k cout << "~Parent() : " << ms << endl; } }; 1 q ~; Z8 K' ]* a class Child : public Parent { Object mO1; Object mO2; string ms;6 H' |6 C- T1 `: o# M U# r" u public:- l8 E/ Z( q4 c" E+ j Child() : mO1("Default 1"), mO2("Default 2")1 y+ E5 h7 E7 k! o; X/ H2 b { cout << "Child()" << endl; ms = "Default"; }/ A3 t8 t1 Z, a2 B. S Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")# t3 n% i- s* r& i4 e {. Z3 J) G/ n; K2 ?( c! d' P. a y" t cout << "Child(string s) : " << s << endl; ms = s;7 `. N G) e. W2 K6 H0 N } ~Child()# f/ ~: T1 q8 l% \. l6 J) S { cout << "~Child() " << ms << endl; }& d6 x3 o/ f6 N3 I. v0 v0 i };: F J: L& j: F2 i) h9 V - }5 a+ c+ b1 _# ]- U7 g# u; r+ q8 h7 X int main() { Child cc("cc");0 {$ Y( E7 Z; X) s* a 2 R4 h! m t: B* e+ n* D cout << endl; return 0; } ( w# w1 D) Y+ M& u3 X 输出结果: root@txp-virtual-machine:/home/txp# ./a.out" \; W, V: f3 u& }0 T' a) `Object(string s) : cc8 F5 H2 M, v) r" q; Z Parent(string s) : cc Object(string s) : cc 18 ^( F4 M- l! C: q0 h Object(string s) : cc 2) n4 g1 R& O8 U' H Child(string s) : cc4 _$ G+ \! Y0 q1 j0 H: J5 Q 0 \' K4 z! q6 Q ~Child() cc ~Object() : cc 2 ~Object() : cc 1- @; O0 n& y; @8 S+ s+ p$ J ~Parent() : cc: s) e1 X- ^. f# x' ~/ } P ~Object() : cc 三、总结:
好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。 |
微信公众号
手机版