实例导入:
(1)dma.h:
//dma.h -- inheritance and dynamic memory allocation #ifndef DMA_H_ #define DMA_H_ #include<iostream> //Brass Class Using DMA class baseDMA { private: char* m_label; int m_rating; public: baseDMA(const char* label = "null", int rating = 0); baseDMA(const baseDMA& rs); virtual ~baseDMA(); baseDMA& operator=(const baseDMA& rs); friend std::ostream& operator<<(std::ostream& os, const baseDMA& rs); }; class lacksDMA :public baseDMA { private: enum { COL_LEN = 40 }; char color[COL_LEN]; public: lacksDMA(const char* c = "blank", const char* label = "null", int rating= 0); lacksDMA(const char* c, const baseDMA& rs); friend std::ostream& operator<<(std::ostream& os, const lacksDMA& rs); }; class hasDMA :public baseDMA { private: char* m_style; public: hasDMA(const char* style = "none", const char* label = "null", int rating = 0); hasDMA(const char* style, const baseDMA& rs); hasDMA(const hasDMA& hs); ~hasDMA(); hasDMA& operator=(const hasDMA& rs); friend std::ostream& operator<<(std::ostream& os, const hasDMA& rs); }; #endif
(2)dma.cpp
//dma.cpp -- dma class methods #include"dma.h" #include<cstring> //Brass Class Using DMA baseDMA::baseDMA(const char* label = "null", int rating = 0) { m_label = new char[std::strlen(label) + 1]; std::strcpy(m_label, label); m_rating = rating; } baseDMA::baseDMA(const baseDMA& rs) { m_label = new char[std::strlen(rs.m_label) + 1]; std::strcpy(m_label, rs.m_label); m_rating = rs.m_rating; } baseDMA::~baseDMA() { delete[] m_label; } baseDMA& baseDMA::operator=(const baseDMA& rs) { if (this == &rs) return *this; delete[]m_label; m_label = new char[std::strlen(rs.m_label) + 1]; std::strcpy(m_label, rs.m_label); m_rating = rs.m_rating; return *this; } std::ostream& operator<<(std::ostream& os, const baseDMA& rs) { os << "Label: " << rs.m_label << std::endl; os << "Rating: " << rs.m_rating << std::endl; return os; } lacksDMA::lacksDMA(const char* c = "blank", const char* label = "null", int rating = 0) :baseDMA(label, rating) { std::strncpy(color, c, 39); color[39] = '\0'; } lacksDMA::lacksDMA(const char* c, const baseDMA& rs) { std::strncpy(color, c, COL_LEN - 1); color[COL_LEN - 1] = '\0'; } std::ostream& operator<<(std::ostream& os, const lacksDMA& rs) { os << (const baseDMA&)rs; os << "Color: " << rs.color << std::endl; return os; } hasDMA::hasDMA(const char* style = "none", const char* label = "null", int rating = 0) :baseDMA(label, rating) { m_style = new char[std::strlen(style) + 1]; std::strcpy(m_style, style); } hasDMA::hasDMA(const char* style, const baseDMA& rs) :baseDMA(rs) { m_style = new char[std::strlen(style) + 1]; std::strcpy(m_style, style); } hasDMA::hasDMA(const hasDMA& hs) :baseDMA(hs) { m_style = new char[std::strlen(hs.m_style) + 1]; std::strcpy(m_style, hs.m_style); } hasDMA::~hasDMA() { delete[] m_style; } hasDMA& hasDMA::operator=(const hasDMA& rs) { if (this == &rs) return *this; baseDMA::operator=(rs); delete[]m_style; m_style = new char[std::strlen(rs.m_style) + 1]; std::strcpy(m_style, rs.m_style); return *this; } std::ostream& operator<<(std::ostream& os, const hasDMA& rs) { os << (const baseDMA&)rs; os << "Style: " << rs.m_style << std::endl; return os; }
(3)usedma.cpp
//usedma.cpp -- inheritance, friends, and DMA //complie with dma.cpp #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 << "Displaying baseDMA object: \n"; cout << shirt << endl; cout << "Displaying lacksDMA object:\n"; cout << balloon << endl; cout << "Displaying hasDMA object:\n"; cout << map << endl; lacksDMA balloon2(balloon); cout << "Result of lacksDMA copy:\n"; cout << balloon2 << endl; hasDMA map2; map2 = map; cout << "Result of hasDMA assignment:\n"; cout << map2 << endl; return 0; }
(1)
virtual ~baseDMA(); …… baseDMA::baseDMA(const char* label = "null", int rating = 0) { m_label = new char[std::strlen(label) + 1]; std::strcpy(m_label, label); m_rating = rating; } baseDMA::~baseDMA() { delete[] m_label; }
类继承中使用动态联编时,必须将析构函数声明为虚函数,在程序结束时派生类会先调用自
身的析构函数,在调用基类的析构函数依次释放new所储存的内存。
(2)
friend std::ostream& operator<<(std::ostream& os, const hasDMA& rs); std::ostream& operator<<(std::ostream& os, const hasDMA& rs) { os << (const baseDMA&)rs; os << "Style: " << rs.m_style << std::endl; return os; }
作为hasDMA类的友元,其可以访问m_style成员,且因为友元不是成员函数,不能使用作用域解
析运算符来指出要使用哪个函数,所以需要使用强制类型转换以便于匹配原型时使用正确的函数。
也可以用dynamic_cast<>来进行强制类型转换,如:
os << dynamic_cast<const baseDMA &> (rs);