继承之动态内存分配&深拷贝浅拷贝

来源:互联网 发布:sql 返回true false 编辑:程序博客网 时间:2024/05/29 06:47

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"//baseDMAbaseDMA::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;}//lacksDMAlacksDMA::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;}//hasDMAhasDMA::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 baseDMAlabel--->hello baseDMAlabel--->hi baseDMAlabel--->hello baseDMAlabel--->这个函数测试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' colorlabel--->hello baseDMA' lable来自baseDMA析构函数(地址:0018F538)color--->hello lacksDMA' colorlabel--->hi baseDMA' lable来自baseDMA析构函数(地址:0018F538)color--->hi lacksDMA' colorlabel--->hello baseDMA' lable来自baseDMA析构函数(地址:0018F538)color--->hello lacksDMA' colorlabel--->这个函数测试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' stylelabel--->hello baseDMA' lable来自baseDMA析构函数(地址:0018F538)style--->hello baseDMA' stylelabel--->hi baseDMA' lable来自baseDMA析构函数(地址:0018F538)style--->hi baseDMA' stylelabel--->hello baseDMA' lable来自baseDMA析构函数(地址:0018F538)style--->hello baseDMA' stylelabel--->这个函数测试hasDMA析构函数生效情况来自baseDMA析构函数(地址:0018F440)style--->这个函数测试hasDMA析构函数生效情况来自hasDMA析构函数(地址:0018F5FC)来自baseDMA析构函数(地址:0018F5FC)*/system("pause");}/*总结:1,派生类里面没有使用动态内存分配 那么复制构造函数,析构函数和赋值函数都不用重写(用编译器提供的默认潜拷贝就可以了)1),默认拷贝遇到char字符串会用strcpy进行复制.2,派生类里面使用动态内存分配 那么派生来的复制构造函数,析构函数和赋值函数都要重写(如果不重写编译器使用浅拷贝拷贝原对象的地址 那么原对象被析构以后 拷贝它的对象就会出现问题)3,在派生来的重载<<运算数输出里面,要显示调用基类的重载<<运算符1)且调用的时候要将派生类强制转换为基类,2)强制转换的时候编译器会弄出来一个临时对象4,派生类里面使用动态内存分配的时候 析构函数要写为虚函数 派生类里面要重新实现析构函数 析构派生来里面动态分配的变量1)(在派生类里面的析构函数不用显示调用基类的析构函数,若调用 将出错)5,*/



0 0
原创粉丝点击