实例导入:
(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);