//头文件
#include <iostream>
#ifndef STRNGBAD_H_
#define STRNGBAD_H_
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);
};

class lacksDMA:public baseDMA


{
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);
};
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
//源文件
#include "dma.h"
#include <cstring>

baseDMA::baseDMA(const char * l,int r)


{
label=new char[std::strlen(l)+1];
std::strcpy(label,l);
this->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没有定义复制构造函数,因为对于它来说浅Copy已经够了,它没有动态分配的内存.对于基类部分,编译器会自动调用基类的复制构造函数(基类有动态分配的内存)

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)


{
std::strncpy(color,c,COL_LEN-1);
color[COL_LEN-1]='\0';
}

std::ostream & operator<<(std::ostream & os,const lacksDMA & ls)


{
//强制类型转换,以调用基类的friend std::ostream & operator << (std::ostream & os,const baseDMA & rs)的操作符重载
os<<(const baseDMA & )ls;
os<<"Color:"<<ls.color<<std::endl;
return os;
}


/**////

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):baseDMA(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);
style=new char[std::strlen(hs.style)+1];
std::strcpy(style,hs.style);
return *this;
}

std::ostream & operator<<(std::ostream & os,const hasDMA & hs)


{
//强制类型转换,以调用基类的friend std::ostream & operator << (std::ostream & os,const baseDMA & rs)的操作符重载
os<<(const baseDMA &)hs;
os<<"Style"<<hs.style<<std::endl;
return os;
}
//调用测试
// dd.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>
#include <cmath>
#include <string>
#include <fstream>
#include "dma.h"

int _tmain(int argc, _TCHAR* argv[])


{
using std::cout;
using std::endl;
baseDMA shirt("Protabelly",8);
lacksDMA balloon("red","Blimpo",4);
hasDMA map("Mercator","Buffalo Keys",5);
cout<<shirt<<endl;
cout<<balloon<<endl;
cout<<map<<endl;
lacksDMA balloon2(balloon);
hasDMA map2;
map2=map;
cout<<balloon2<<endl;
cout<<map2<<endl;
return 0;
}
//输出结果
Label:Protabelly
Rating:8

Label:Blimpo
Rating:4
Color:red

Label:Buffalo Keys
Rating:5
StyleMercator

Label:Blimpo
Rating:4
Color:red

Label:Buffalo Keys
Rating:5
StyleMercator


第一段是基类的输出,这个没有什么问题.
第二段是调用子类lacksDMA的<<重载函数,可以看到已经调用了基类的<<重载函数,是通过
os<<(const baseDMA & )ls;调用的.(*****重要*****)
第三段是调用子类hasDMA的<<重载函数,可以看到没有问题,说明它的继承关系是正常的.
第四段是调用了lacksDMA的复制构造函数,因为这个子类的成员并没有通过new动态分配的内存,所以没有自己定义复制构造函数,而是让编译器自己生成的,通过结果可以看到,虽然没有自己定义,但是编译器还是调用了基类的自定义的复制构造函数,因为基类的label是动态分配的.
第五段是调用了hasDMA的=重载函数,这个函数里,要手工去调用
baseDMA::operator =(hs);以构造基类部分,以使对象完整.重载的<<与上面是相同的..(*****重要*****)
一点说明:为什么在标题中要嵌入英文?原因是为了能够让国外的网友能查询到这篇文章。平常在Google上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现