分享

C++ Primer Plus 十三章 类的继承 DMA程序 源代码及附注 vs2012通过

 松静无为 2013-05-08
// 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;
}


 
 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多