C++学习-----------------类继承之公有继承

//1.给出一个简单的类声明,然后要求你派生出一个指定的类,并进行测试。 
 
//第一个Music.h

#ifndef MUSIC_H_
#define MUSIC_H_

#include<iostream>

class Cd
{
private:
	char performers[50] ;
	char label[20] ;
	int selections ;
	double playtime ;

public:
	Cd(const char *s1 ,const  char *s2 , int n , double x ) ;
	Cd() ;
	~Cd(){} ;
	virtual void Report() const ;
	Cd & operator = (const Cd &d) ;
} ;


class Classic : public Cd
{
private :
	char m_works[50] ;

public:
	Classic(const char *works ,const char *s1 ,const char *s2,int n ,double x) ;
	Classic() ;
	~Classic(){} ;
	virtual void Report() const ;
} ;


#endif





//Classic.cpp
#include<iostream>
#include<cstring>
#include"Music.h"

Cd::Cd()
{ 
	strcpy(performers,"None");
	strcpy(label,"None") ;
	selections = 0 ;
	playtime = 0.0 ;
}

Cd::Cd(const char *s1, const char *s2,int n , double x) 
{
	strncpy(performers,s1,49) ;
	performers[19] = '\0' ;
	strncpy(label,s2,19) ;
	label[19] = '\0' ;
	selections = n ;
	playtime = x ;
}


void Cd::Report()const
{
	using std::cout ;
	using std::endl ;
	
	cout << "Performers : " << performers << endl ;
	cout << "Label : " << label << endl ;
	cout << "Selections : " << selections << endl ;
	cout << "Playtime : " << playtime << endl ;
}

Cd & Cd::operator=(const Cd &d)
{
	strncpy(performers,d.performers,49) ;
	strncpy(label,d.label,19) ;
	selections = d.selections ;
	playtime = d.playtime ;

	return *this ;
}


Classic::Classic():Cd()
{
	strcpy(m_works,"None") ;
}


Classic::Classic(const char *works,const char *s1,const char *s2,int n ,double x):Cd(s1,s2,n,x) 
{
	strncpy(m_works,works,49) ;   //复制长度指定很重要,如果超出了本来数组的长度,则可能会出现覆盖其他内存区域。。
	m_works[49] = '\0' ;          //但是这里指定的长度也不能超过本来数组的长度,否则的话一样会出错。。
}

void Classic::Report() const
{
	using std::cout ;
	using std::endl ;
	
	cout << "Most Work : " << m_works << endl ;
	Cd::Report() ;
}




//main.cpp
#include<iostream>
#include"Music.h"


void Bravo(const Cd &disk) ;


int main(void)
{	
	using std::cout ;
	using std::endl ;

	Cd c1("Beatles","Captiol",14,35.5) ;
	Classic c2 = Classic("Piano Sonata in B flat,Fantasia in C" ,
						"Alfred Brendel" ,"Philips",2,57.17) ;  //problem coming inot being here
	Cd *pcd = &c1 ;

	cout << "Using object directly : \n" ;
	c1.Report() ;
	c2.Report() ;

	cout << "Using type Cd * pointer to object: \n" ;
	pcd->Report() ;
	pcd = &c2 ;
	pcd->Report() ;


	cout << "Calling a function with a Cd reference argument :\n" ;
	Bravo(c1) ;
	Bravo(c2) ;

	cout << "Testing assignment :" ;
	Classic copy ;
	copy = c2 ;
	copy.Report() ;

	return 0 ;

}


void Bravo(const Cd &disk) 
{
	disk.Report() ;

}


 

 

 第二个,动态分配内存版本

//Music.h


#ifndef MUSIC_H_
#define MUSIC_H_

#include<iostream>

class Cd
{
private:
	char *performers ;
	char *label ;
	int selections ;
	double playtime ;

public:
	Cd(const char *s1 ,const  char *s2 , int n , double x ) ;
	Cd() ;
	~Cd() ;
	virtual void Report() const ;
	Cd & operator=(const Cd &d) ;
	Cd(const Cd &d) ;
} ;


class Classic : public Cd
{
private :
	char *m_works ;

public:
	Classic(const char *works ,const char *s1 ,const char *s2,int n ,double x) ;
	Classic() ;
	~Classic() ;
	virtual void Report() const ;
	Classic & operator=(const Classic &c) ;
	Classic(const Classic &c) ;
} ;


#endif


 

//Classic.cpp

#include<iostream>
#include<cstring>
#include"Music.h"
#include<cstdlib>


//Cd public method

Cd::Cd()
{ 	
	performers = NULL ;
	label = NULL ;
	selections = 0 ;
	playtime = 0.0 ;
}

Cd::Cd(const char *s1, const char *s2,int n , double x) 
{
	int m  = 0 ;
	m = strlen(s1) ; 
	performers = new char[m+1] ;
	strcpy(performers,s1) ;

	m = strlen(s2) ;
	label = new char[m+1] ;
	strcpy(label,s2) ;

	selections = n ;
	playtime = x ;
}


void Cd::Report()const
{
	using std::cout ;
	using std::endl ;
	
	cout << "Performers : " << performers << endl ;
	cout << "Label : " << label << endl ;
	cout << "Selections : " << selections << endl ;
	cout << "Playtime : " << playtime << endl ;
}



Cd::Cd(const Cd &d)          //复制构造函数,觉得这一个比较重要,问题往往就出在这里。这一个用在初始化或者需要临时对象的时候
{
	int len = 0 ;
	len = strlen(d.performers) ;
	performers = new char [len+1] ;
	strcpy(performers,d.performers) ;

	len = strlen(d.label) ;
	label = new char [len+1] ;
	strcpy(label,d.label) ;

	selections = d.selections ;
	playtime = d.playtime ;
}


Cd & Cd:: operator=(const Cd &d)  //通常有了复制构造函数,赋值操作符都要重载。不过这一个是用在赋值过程
{
	int len = 0 ;
	if(this == &d)
		return *this ;
	
	delete [] performers ;
	delete [] label ;

	len = strlen(d.performers) ;
	performers = new char[len+1] ;
	strcpy(performers,d.performers) ;


	len = strlen(d.label) ;
	label = new char[len+1] ;
	strcpy(label,d.label) ;

	selections = d.selections ;
	playtime = d.playtime ;

	return *this ;

}

Cd::~Cd()   //动态分配时就要显式定义析构函数
{
	delete [] performers ;
	delete [] label ;
}


//Classic public method


Classic::Classic(const Classic &c):Cd(c)    //派生类的复制构造函数会在初始化成员列表中调用基类的构造函数为初始化基类部分的组件
{
	int  len = 0 ;
	len = strlen(c.m_works) ;
	m_works = new char [len+1] ;
	strcpy(m_works,c.m_works) ;
}

Classic::Classic():Cd()
{
	m_works = NULL ;
}


Classic::Classic(const char *works,const char *s1,const char *s2,int n ,double x):Cd(s1,s2,n,x)   //同上
{
	int m = 0 ;
	m = strlen(works) ;
		
	m_works = new char[m+1] ;

	strncpy(m_works,works,m+1) ;   //复制长度指定很重要,如果超出了本来数组的长度,则可能会出现覆盖其他内存区域。。
	m_works[m] = '\0' ;          //但是这里指定的长度也不能超过本来数组的长度,否则的话一样会出错。。
}

void Classic::Report() const
{
	using std::cout ;
	using std::endl ;
	
	cout << "Most Work : " << m_works << endl ;
	Cd::Report() ;                                   //输出显示可以用作用域解析符去显式调用基类的方法
}


Classic & Classic:: operator=(const Classic &c)
{
	int len = 0 ;
	if(this == &c)
		return *this ;
	Cd::operator=(c) ;                   //注意这里,道理一样,大家都懂的

	len = strlen(c.m_works) ;
	m_works = new char [len+1] ;
	strcpy(m_works,c.m_works) ;	
		
	return *this ;
}




Classic::~Classic()           //派生类会自动调用基类的析构函数,所以不用我们去写
{
	delete [] m_works ;
}


 

//main.cpp

#include<iostream>
#include"Music.h"


void Bravo(const Cd &disk) ;


int main(void)
{	
	using std::cout ;
	using std::endl ;

	Cd c1("Beatles","Captiol",14,35.5) ;
	Classic c2 = Classic("Piano Sonata in B flat,Fantasia in C" ,
						"Alfred Brendel" ,"Philips",2,57.17) ;  
	Cd *pcd = &c1 ;

	cout << "\n\nUsing object directly : \n" ;
	c1.Report() ;
	c2.Report() ;

	cout << "\n\nUsing type Cd * pointer to object: \n" ;
	pcd->Report() ;
	pcd = &c2 ;
	pcd->Report() ;


	cout << "\n\nCalling a function with a Cd reference argument :\n" ;
	Bravo(c1) ;
	Bravo(c2) ;

	cout << "\n\nTesting assignment :" ;
	Classic copy ;
	copy = c2 ;
	copy.Report() ;

	return 0 ;

}


void Bravo(const Cd &disk) 
{
	disk.Report() ;
}


 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值