关于C++继承时的友元函数的使用解决思路

关于C++继承时的友元函数的使用
这个例子是
CPP书上的例子  

代码如下  
头文件 :dma.h
#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::iostream & os, const baseDMA & rs);
};

// derived class without DMA
// no destructor needed
// uses implicit copy constructor
// uses implicit assignment operator
class lacksDMA : public baseDMA
{
private:
enum { COL_LEN = 40};
char color [COL_LEN];

public:
lacksDMA (const char * c = "black",const char *l = "null",int t = 0);
lacksDMA (const char * c, const baseDMA & rs);
friend std::ostream operator << (std::ostream & os,const lacksDMA);

};

// 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

#include "stdafx.h"
#include "dma.h"
#include <iostream>
#include <cstring>


baseDMA::baseDMA (const char * l, int r)
{
label = new char [std::strlen (l) + 1];
std::strcpy (label,l);
rating = r;
}

baseDMA::baseDMA (const baseDMA & rs)
{
label = new char [std::strlen(rs.label) + 1];
std::strcpy (label,rs.label);
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);
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);
color [39] = '\0';
}

lacksDMA::lacksDMA (const char * c,const baseDMA & rs) : baseDMA (rs)
{
std::strncpy (color,c,COL_LEN - 1);
color [COL_LEN - 1] = '\0';
}
std::ostream & operator<<(std::ostream & os, const lacksDMA & ls) //lacksDMA的友元
{
os << (const baseDMA &) ls;
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);
}

hasDMA::hasDMA (const char * s, const baseDMA & rs)
:baseDMA (rs)
{
style = new char [std::strlen(s) + 1];
std::strcpy (style,s);
}

hasDMA::hasDMA (const hasDMA & hs)
{
style = new char [std::strlen (hs.style) + 1];
std::strcpy (style,hs.style);
}
hasDMA::~hasDMA ()
{
delete [] style;
}

hasDMA & hasDMA::operator=(const hasDMA & hs)
{
if (this == &hs)
return * this;
baseDMA::operator=(hs); //copy base portion
delete [] style;
style = new char [std::strlen (hs.style) + 1];
std::strcpy (style,hs.style);

return * this;