继承与动态内存分配
繼承與動態(tài)內(nèi)存分配
在基類或派生類中含有指針時,要考慮內(nèi)存分配情況(new與delete),還要考慮在進行對象間賦值時指針隱藏的問題(使用默認復制構(gòu)造函數(shù)在析構(gòu)時會造成原對象中的指針指向的內(nèi)存空間被釋放,為淺復制)
因此需要:
1. 重載運算符’=‘、’<<‘,實現(xiàn)深度復制;
2. 在構(gòu)造函數(shù)中使用new進行動態(tài)內(nèi)存分配,在析構(gòu)函數(shù)中使用delete進行內(nèi)存釋放;
3. 將析構(gòu)函數(shù)聲明為虛函數(shù)
在以下代碼中還有一個小技巧來簡化代碼,即代碼重用,在后續(xù)代碼中使用已定義過的代碼,例如:在C的構(gòu)造函數(shù)中使用已經(jīng)定義過的A的構(gòu)造函數(shù),這樣就可以只對C類新增的數(shù)據(jù)部分進行初始化。
#include <iostream> #include <string> #include <cstring> using namespace std;class A { private: char *label; //使用指針,需要動態(tài)分配內(nèi)存int a; public: A( const char* l = "null", int t = 0 );A( const A& t );virtual ~A();A& operator=( const A& t );friend ostream& operator<<( ostream& out, const A& t ); };class B : public A { private: enum{ COL_LEN = 40 };char color[COL_LEN]; //使用數(shù)組,不需要重新分配內(nèi)存 public: B( const char *c = "blank", const char *l = "null", int t = 0 );B( const char *c, const A& t );friend ostream& operator<<( ostream& out, const B& t ); };class C : public A { private: char *style; public: C( const char *s = "none", const char * l = "null", int t = 0 );C( const char *s, const A& t );C( const C& t );~C();C& operator=( const C& t );friend ostream& operator<<( ostream& out, const C& t ); };// A methods A::A( const char *l, int t ) {label = new char[ strlen(l) + 1 ];strcpy( label, l );a = t; }A::A( const A& t ) {label = new char[ strlen(t.label) + 1 ];strcpy( label, t.label );a = t.a; }A::~A() {delete[] label; }A& A::operator=( const A& t ) {/* 若為同一對象,則直接返回,否則會將該對象內(nèi)容delete,無法復制 */if ( this == &t ) {return *this;}delete[] label; //先釋放原內(nèi)存空間label = new char[ strlen(t.label)+1 ];strcpy( label, t.label );a = t.a;return *this; }ostream& operator<<( ostream& out, const A& t ) {out << "label = " << t.label << ", a = " << t.a << endl;return out; }// B methods B::B( const char *c, const char *l, int t ) : A( l, t ) {strcpy( color, c ); }B::B( const char *c, const A& t ) : A(t) {strcpy( color, c ); }ostream& operator<<( ostream& out, const B& t ) {out << ( const A& )t;out << "color = " << t.color << endl;return out; }// C methods C::C( const char *s, const char *l, int t ) : A( l, t ) {style = new char[ strlen(s)+1 ];strcpy( style, s ); }C::C( const char *s, const A& t ) : A( t ) {style = new char[ strlen(s)+1 ];strcpy( style, s ); }C::C( const C& t ) : A(t) {style = new char[ strlen(t.style)+1 ];strcpy( style, t.style ); }C::~C() {delete[] style; }C& C::operator=( const C& t ) {if ( this == &t ) {return *this;}A::operator=(t); //調(diào)用A類的賦值函數(shù)初始化,相當于 *this = t;delete[] style;style = new char[ strlen(t.style)+1 ];strcpy( style, t.style );return *this; }ostream& operator<<( ostream& out, const C& t ) {out << ( const A& )t; //類型強轉(zhuǎn),使用A類的<<運算符重載函數(shù)out << "style = " << t.style << endl;return out; }int main() {A shirt( "portabelly", 8 );B balloon( "red", "Blimpo", 4 );C map( "Mercator", "Buffalo", 5 );cout << "A:\n" << shirt << endl;cout << "B:\n" << balloon << endl;cout << "C:\n" << map << endl;B balloon2(balloon);cout << "balloon2:\n" << balloon2 << endl;return 0; }總結(jié)
- 上一篇: 友元函数 友元类 友元成员函数
- 下一篇: 原发性不孕症治疗