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


第一段是基类的输出,这个没有什么问题.
第二段是调用子类lacksDMA的<<重载函数,可以看到已经调用了基类的<<重载函数,是通过os<<(const baseDMA & )ls;调用的.(*****重要*****)
第三段是调用子类hasDMA的<<重载函数,可以看到没有问题,说明它的继承关系是正常的.

第四段是调用了lacksDMA的复制构造函数,因为这个子类的成员并没有通过new动态分配的内存,所以没有自己定义复制构造函数,而是让编译器自己生成的,通过结果可以看到,虽然没有自己定义,但是编译器还是调用了基类的自定义的复制构造函数,因为基类的label是动态分配的.
第五段是调用了hasDMA的=重载函数,这个函数里,要手工去调用baseDMA::operator =(hs);以构造基类部分,以使对象完整.重载的<<与上面是相同的..(*****重要*****)
posted @ 2008-01-18 16:49  吴东雷  阅读(1866)  评论(0编辑  收藏  举报