// dma.h inheritance and dynamic memory allocation 继承和动态内存分配 #ifndef DMA_H_ #define DMA_H_ #include <iostream> //Base class using DMA class baseDMA //基类 { private: char * label; int rating; public: baseDMA (const char* l="null" , int r=0); //默认构析函数 baseDMA (const baseDMA & rs); //结构复制构析函数 virtual ~baseDMA(); //虚析构函数 baseDMA & operator=(const baseDMA & rs); //=操作符重载函数 friend std::ostream & operator<< (std::ostream & os ,const baseDMA & rs); // <<操作符重载友元函数 }; //derived class without DMA DMA派生类 //no destructor needed 无销毁需求 //uses implicit copy constructor 使用显式结构复制 //uses implicit assignment operator 使用显式赋值操作符 class lacksDMA:public baseDMA //从baseDMA基类派生出类lcksDMA { private: enum {col_len =40}; //以枚举类来提供常数 char color[col_len]; public: lacksDMA (const char * c ="blank", const char * l = "null", int r = 0); lacksDMA (const char * c, const baseDMA &rs); friend std::ostream & operator<<(std::ostream & os , const lacksDMA & rs); }; //derived class with DMA class hasDMA:public baseDMA { private: char * style; public: hasDMA (const char * s ="none", const char * l ="null", int r =0); hasDMA(const char * s , const baseDMA & rs); hasDMA(const hasDMA & hs); ~hasDMA(); hasDMA & operator=(const hasDMA & rs); friend std::ostream & operator<< (std::ostream & os , const hasDMA & rs); }; #endif //dma.cpp dma class methods //1. 派生类的的构析函数只负责派生类中新增的数据对你的创建与赋值,与基类共有的数据对像均显式的调用基类构造函数来完成创造与赋值 //如: lacksDMA::lacksDMA(const char * c, const char *l , int r): baseDMA(l,r) //2. 对于使用了new来创造内存空间的部份,派生类只负责派生类中新增的数据对像使用new后在对应析构函数中调用delete, 而属于基类的数据对像则由基类的析构函数负责调用delete销毁。 #include "dma.h" #include <cstring> //baseDMA methods baseDMA::baseDMA(const char *l ,int r) { label = new char [std::strlen(l) + 1]; //std::strcpy(label ,l); strcpy_s(label , sizeof(char) * ( std::strlen (l) +1 ) , l); rating = r; } baseDMA::baseDMA(const baseDMA & rs) { label = new char[std::strlen(rs.label) + 1]; //std::strcpy(label , rs.label); strcpy_s(label , sizeof(char) * ( std::strlen(rs.label) + 1 ) , rs.label); //strcpy函数自vs2005版本起被认为不安全,应使用strcpy_s()代替 rating = rs.rating; } baseDMA::~baseDMA() { delete [] label; } baseDMA & baseDMA::operator=(const baseDMA & rs) { if (this == & rs) return *this; delete [] label; label = new char [std::strlen(rs.label) + 1]; //std::strcpy (label , rs.label); strcpy_s(label , sizeof(char) * ( std::strlen(rs.label) + 1 ) , rs.label); rating = rs.rating; return *this; } std::ostream & operator<<(std::ostream & os ,const baseDMA & rs) { os << "label: "<<rs.label << std::endl; os << "rating: "<< rs.rating << std::endl; return os; } //lacksDMA methods lacksDMA::lacksDMA(const char * c, const char *l , int r): baseDMA(l,r) { //std::strncpy(color, c, 39); strncpy_s(color,c,39); color[39] = '\0'; } lacksDMA::lacksDMA(const char *c, const baseDMA & rs) :baseDMA(rs) { //std::strncpy(color, c ,col_len - 1); strncpy_s(color, c ,col_len - 1); color[col_len -1] = '\0'; } std::ostream & operator<<(std::ostream & os , const lacksDMA & ls) { os << (const baseDMA &) ls; //将ls强制转换成baseDMA & 类型 os <<"color: "<< ls.color << std::endl; return os; } //hasDMA methods hasDMA::hasDMA (const char *s ,const char * l, int r):baseDMA(l,r) { style = new char [std::strlen (s) + 1 ]; //std::strcpy(style, s); strcpy_s(style , sizeof(char) * ( std::strlen (s) + 1 ) , s); } hasDMA::hasDMA(const char * s, const baseDMA & rs):baseDMA(rs) { style = new char [std::strlen(s) + 1 ]; //std::strcpy (style , s); strcpy_s(style , sizeof(char) * ( std::strlen (s) + 1 ) , s); } hasDMA::hasDMA (const hasDMA & hs):baseDMA(hs) { style = new char [ std::strlen(hs.style) + 1]; //std::strcpy (style, hs.style); strcpy_s(style , sizeof(char) * ( std::strlen(hs.style) + 1 ) , hs.style); } hasDMA::~hasDMA() { delete [] style; } hasDMA & hasDMA::operator= (const hasDMA & hs) { if (this == & hs) return *this; baseDMA::operator=(hs); //copy base portion style = new char [std::strlen (hs.style) + 1 ]; //std::strcpy(style, hs.style); strcpy_s(style , sizeof(char) * ( std::strlen(hs.style) + 1 ) , hs.style); return *this; } std::ostream & operator<<(std::ostream & os , const hasDMA &hs) { os << (const baseDMA &) hs; os << "style: " << hs.style << std:: endl; return os; } //usedma.cpp inheritance , friends , and DMA //compile whih dma.cpp //3. 在实际使用基类与派生类时,一般总是按照 调用函数的对像 属于哪个类 来匹配调用相应的函数。 #include <iostream> #include "dma.h" int main() { using std::cout; using std::endl; baseDMA shirt ("Portabelly" , 8); lacksDMA balloon ("red" , "Blimpo", 4); hasDMA map ("mercator" , "Buffalo Keys" , 5); cout<< shirt <<endl; //baseDMA基类的重载<<操作符友元函数 cout<<balloon<<endl; //lacksDMA派生类的重载<<操作符友元函数 cout << map << endl; //hasDMA派生类的重载<<操作符友元函数 lacksDMA balloon2 (balloon); //调用lacksDMA派生类的结构复制构析函数 hasDMA map2; map2 = map; //调用hasDMA派生类的 重载=号操作符函数 cout << balloon2 <<endl; cout << map2 << endl; system("pause"); //暂停屏幕 return 0; } |
|