friend std::ostream & operator<< (std::ostream & os ,const baseDMA & rs); // <<操作符重载友元函数
//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;
}