baseDMA.h
#ifndef BASEDMA_H_
#define BASEDMA_H_
#include <iostream>
//基类
class baseDMA
{
private:
char *label; //动态内存分配
public:
baseDMA(const char *l = "null"); //构造函数
baseDMA(const baseDMA & rs); //复制函数
virtual ~baseDMA();
baseDMA & operator = (const baseDMA & rs); //赋值函数
friend std::ostream & operator<<(std::ostream & os,const baseDMA & ou_ob);
};
//派生类不使用动态内存分配
class lacksDMA:public baseDMA
{
private:
char color[100];
public:
lacksDMA(const char *co = "null",const char *l = "null");
friend std::ostream & operator<<(std::ostream & os,const lacksDMA & ou_ob);
};
//派生类使用动态内存分配
class hasDMA:public baseDMA
{
private:
char *style; //动态内存分配
public:
hasDMA(const char *l = "null", const char *s = "null"); //构造函数
hasDMA(const hasDMA & ha);//复制函数
hasDMA & operator = (const hasDMA & ha);
virtual ~hasDMA();
friend std::ostream & operator<<(std::ostream & os,const hasDMA & ou_ob);
};
#endif
baseDMA.cpp
#include "baseDMA.h"
//baseDMA
baseDMA::baseDMA(const char *l)
{
label = new char[std::strlen(l)+1];
std::strcpy(label,l);
}
baseDMA::baseDMA(const baseDMA & re)
{
this->label = new char[std::strlen(re.label)+1];
std::strcpy(this->label,re.label);
}
baseDMA::~baseDMA()
{
std::cout << "来自baseDMA析构函数" << "(地址:" << this <<")\n";
delete [] this->label;
}
baseDMA & baseDMA::operator=(const baseDMA & rs)
{
if(this == &rs) //如果是同样的一个相互复制 直接return
{
return *this;
}
delete [] this->label;
this->label = new char [std::strlen(rs.label) + 1];
std::strcpy(this->label,rs.label);
return *this;
}
std::ostream & operator<<(std::ostream & os,const baseDMA & ou_ob)
{
os<< "label--->" << ou_ob.label << std::endl;
return os;
}
//lacksDMA
lacksDMA::lacksDMA(const char *co, const char *l):baseDMA(l)
{
std::strcpy(this->color,co);
}
std::ostream &operator<<(std::ostream & os, const lacksDMA & ou_ob)
{
os << (baseDMA)ou_ob; //强制装换调用基类的重载输出
//std::cout << &(baseDMA)ou_ob << std::endl;
//这里强制转换 编译器会弄出来一个baseDMA的临时变量 并且用baseDMA的析构函数去析构它
os << "color--->" << ou_ob.color << std::endl;
return os;
}
//hasDMA
hasDMA::hasDMA(const char *l, const char *s):baseDMA(l)
{
this->style = new char [std::strlen(s) + 1];
std::strcpy(this->style,s);
}
hasDMA::hasDMA(const hasDMA & ha):baseDMA(ha) //复制构造函数
{
this->style = new char [std::strlen(ha.style) + 1];
std::strcpy(this->style,ha.style);
}
hasDMA & hasDMA::operator = (const hasDMA & ha) //赋值函数 //可以直接使用 基类构造函数吗?
{
if(this == &ha)
{
return *this;
}
//使用基类的赋值构造函数
baseDMA::operator=(ha);
delete [] this->style;
std::strcpy(this->style,ha.style);
return *this;
}
hasDMA::~hasDMA() //需要显示的调用 基类的析构函数吗? (不需要 编译器会自动调用 手动在这里在调用一次的话会出问题)
{
std::cout << "来自hasDMA析构函数" << "(地址:" << this <<")\n";
delete [] this->style;
}
std::ostream & operator<<(std::ostream & os,const hasDMA & ou_ob)
{
os << (baseDMA)ou_ob;
os << "style--->" << ou_ob.style << std::endl;
return os;
}
Main.cpp
#include"baseDMA.h"
using std::cout;
void testBaseDestructor()
{
baseDMA base("这个函数测试baseDMA析构函数生效情况");
cout << base;
}
void testLacksDestructor()
{
lacksDMA lacks("这个函数测试lacksDMA析构函数生效情况","这个函数测试lacksDMA析构函数生效情况");
cout << lacks;
}
void testhasDestructor()
{
hasDMA has("这个函数测试hasDMA析构函数生效情况","这个函数测试hasDMA析构函数生效情况");
cout << has;
}
void testSlightCopy(lacksDMA & f) //测试浅拷贝里面 A对象将值拷给B对象以后 A马上执行析构 B还存在吗? (存在)
{
lacksDMA temp("hello","hi");
f = temp; //浅拷贝
}
void main()
{
cout << "/********测试baseDMA********/\n";
baseDMA baseOne("hello baseDMA"); //使用构造函数
cout << baseOne;
baseDMA baseTwo(baseOne); //使用复制构造函数
cout << baseTwo;
baseDMA baseThree("hi baseDMA");
cout << baseThree;
baseThree = baseOne; //使用赋值函数
cout << baseThree;
testBaseDestructor();
//输出结果:
/*label--->hello baseDMA
label--->hello baseDMA
label--->hi baseDMA
label--->hello baseDMA
label--->这个函数测试baseDMA析构函数生效情况
来自baseDMA析构函数(地址:0018F600)*/
cout << "\n\n/********测试lacksDMA********/\n";
lacksDMA lacksOne("hello lacksDMA' color","hello baseDMA' lable");//使用lacksDMA的构造函数(lacksDMA会调用baseDMA的构造函数)
cout << lacksOne;
cout << "\n";
lacksDMA lacksTwo(lacksOne); //使用lacksDMA的复制构造函数
cout << lacksTwo;
cout << "\n";
lacksDMA lacksThree("hi lacksDMA' color","hi baseDMA' lable");
cout << lacksThree;
lacksThree = lacksTwo; //使用lacksDMA的赋值构造函数
cout << lacksThree;
cout << "\n";
testLacksDestructor();
lacksDMA lacksFour("1","2");
cout << lacksFour;
testSlightCopy(lacksFour);
cout << lacksFour;
//输出结果:
/* label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
color--->hello lacksDMA' color
label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
color--->hello lacksDMA' color
label--->hi baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
color--->hi lacksDMA' color
label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
color--->hello lacksDMA' color
label--->这个函数测试lacksDMA析构函数生效情况
来自baseDMA析构函数(地址:0018F3DC)
color--->这个函数测试lacksDMA析构函数生效情况
来自baseDMA析构函数(地址:0018F598) */
cout << "\n\n/********测试hasDMA********/\n";
hasDMA hasOne("hello baseDMA' lable","hello baseDMA' style");//使用hasDMA的构造函数
cout << hasOne;
cout << "\n";
hasDMA hasTwo(hasOne); //使用hasDMA的复制构造函数
cout << hasTwo;
cout << "\n";
hasDMA hasThree("hi baseDMA' lable","hi baseDMA' style");
cout << hasThree;
cout << "\n";
hasThree = hasOne; //使用hasDMA的赋值函数
cout << hasThree;
cout << "\n";
testhasDestructor();
//输出结果:
/*label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
style--->hello baseDMA' style
label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
style--->hello baseDMA' style
label--->hi baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
style--->hi baseDMA' style
label--->hello baseDMA' lable
来自baseDMA析构函数(地址:0018F538)
style--->hello baseDMA' style
label--->这个函数测试hasDMA析构函数生效情况
来自baseDMA析构函数(地址:0018F440)
style--->这个函数测试hasDMA析构函数生效情况
来自hasDMA析构函数(地址:0018F5FC)
来自baseDMA析构函数(地址:0018F5FC)*/
system("pause");
}
/*总结:
1,派生类里面没有使用动态内存分配 那么复制构造函数,析构函数和赋值函数都不用重写(用编译器提供的默认潜拷贝就可以了)
1),默认拷贝遇到char字符串会用strcpy进行复制.
2,派生类里面使用动态内存分配 那么派生来的复制构造函数,析构函数和赋值函数都要重写(如果不重写编译器使用浅拷贝拷贝原对象的地址 那么原对象被析构以后 拷贝它的对象就会出现问题)
3,在派生来的重载<<运算数输出里面,要显示调用基类的重载<<运算符
1)且调用的时候要将派生类强制转换为基类,
2)强制转换的时候编译器会弄出来一个临时对象
4,派生类里面使用动态内存分配的时候 析构函数要写为虚函数 派生类里面要重新实现析构函数 析构派生来里面动态分配的变量
1)(在派生类里面的析构函数不用显示调用基类的析构函数,若调用 将出错)
5,
*/