C++类继承的一个实例,说明了继承的方法,析构的方法,基类构造函数的调用,基类操作符重载
//头文件
#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
#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上查资料的时候,经常参考国外网友的博客,帮助我解决了很多问题,所以我也想让他们能够参考我写的内容。当然文中我不可能全部译为英文,所以我尽量把代码粘全,靠代码说话吧。