继承与动态内存分配
繼承與動態內存分配
在基類或派生類中含有指針時,要考慮內存分配情況(new與delete),還要考慮在進行對象間賦值時指針隱藏的問題(使用默認復制構造函數在析構時會造成原對象中的指針指向的內存空間被釋放,為淺復制)
因此需要:
1. 重載運算符’=‘、’<<‘,實現深度復制;
2. 在構造函數中使用new進行動態內存分配,在析構函數中使用delete進行內存釋放;
3. 將析構函數聲明為虛函數
在以下代碼中還有一個小技巧來簡化代碼,即代碼重用,在后續代碼中使用已定義過的代碼,例如:在C的構造函數中使用已經定義過的A的構造函數,這樣就可以只對C類新增的數據部分進行初始化。
#include <iostream> #include <string> #include <cstring> using namespace std;class A { private: char *label; //使用指針,需要動態分配內存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]; //使用數組,不需要重新分配內存 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 ) {/* 若為同一對象,則直接返回,否則會將該對象內容delete,無法復制 */if ( this == &t ) {return *this;}delete[] label; //先釋放原內存空間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); //調用A類的賦值函數初始化,相當于 *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; //類型強轉,使用A類的<<運算符重載函數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; }總結
- 上一篇: 友元函数 友元类 友元成员函数
- 下一篇: 【动态规划】01背包问题