//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() ;
}