一.Student 类的设计:使用了valarray类(很啰嗦)
1.头文件:
#ifndef STUDENT_H_
#define STUDENT_H_
#include<iostream>
#include<string>
#include<valarray>
using namespace std;
class Student
{
private:
typedef valarray<double> ArrayDb;
string name;
ArrayDb scores;
ostream &arr_out(ostream &os);
public:
Student():name("Null Student"),scores(){}
explicit Student(const string &s):name(s),scores(){}
explicit Student(int n):name("Nully"),scores(n){}
Student(const string &s,int n):name(s),scores(n){}
Student(const string &s,const ArrayDb &a):name(s),scores(a){}
Student(const char *str,const double *pd,int n):name(str),scores(pd,n){}
~Student(){} //以上全是内联函数 实现
double Average();
string &Name();
double &operator[](int i);
double operator[](int i)const;
friend istream &operator>>(istream &is,Student &stu);
friend istream &getline(istream &is,Student &stu);
friend ostream &operator<<(ostream &os, Student &stu);
};
#endif
2.类方法的实现:
#include<iostream>
#include"student.h"
using namespace std;
double Student::Average()
{
if(scores.size()>0)
return scores.sum()/scores.size();
else
return 0;
}
string &Student::Name()
{
return name;
}
double &Student::operator[](int i)
{
return scores[i];
}
double Student::operator[](int i)const
{
return scores[i];
}
ostream &Student::arr_out(ostream &os)
{
int i;
if(scores.size()>0)
{
for(i=0;i<scores.size();i++)
{
os<<scores[i]<<" ";
if(i%5==4)
os<<endl;
}
if(i%5!=0)
os<<endl;
}
else
os<<"empty array";
return os;
}
istream &operator>>(istream &is,Student &stu)
{
is>>stu.name;
return is;
}
istream &getline(istream &is,Student &stu)
{
getline(is,stu.name);
return is;
}
ostream &operator<<(ostream &os,Student &stu)
{
os<<"Scores for"<<stu.name<<":\n";
stu.arr_out(os);
return os;
}
3.测试类:
#include<iostream>
#include"student.h"
using namespace std;
void set(Student &sa,int n);
const int pupils=3;
const int quizzes=5;
int main()
{
Student ada[pupils]={Student(quizzes),Student(quizzes),Student(quizzes)};
int i;
for(i=0;i<pupils;++i)
set(ada[i],quizzes);
cout<<"\nStudent List:\n";
for(i=0;i<pupils;++i)
cout<<ada[i].Name()<<endl;
cout<<"\nResults:";
for(i=0;i<pupils;++i)
{
cout<<endl<<ada[i];
cout<<"average:"<<ada[i].Average()<<endl;
}
cout<<"Done!\n";
return 0;
}
void set(Student &sa,int n)
{
cout<<"Please enter the student's name:";
getline(cin,sa);
cout<<"Please enter"<<n<<"quiz scores:\n";
for(int i=0;i<n;i++)
cin>>sa[i];
while (cin.get()!='\n')
continue;
}
二.私有继承(没有掌握)
三.多重继承
1.此例中一堆没用的构造函数,看起来很别扭。主要是set和show方法。在派生类中调用了基类的set和show方法,来设置和显示共有部分的数据。
#ifndef WORKER_H_
#define WORKER_H_
#include<iostream>
#include<string>
using namespace std;
class Worker
{
private:
string fullname;
long id;
public:
Worker():fullname("none"),id(0L){}
Worker(const string &s,long n):fullname(s),id(n){}
virtual ~Worker()=0;
virtual void Set();
virtual void Show();
};
class Waiter:public Worker
{
private:
int panache;
public:
Waiter():Worker(),panache(0){}
Waiter(const string &s,long n,int p=0):Worker(s,n),panache(p){}
Waiter(const Worker &wk,int p=0):Worker(wk),panache(p){} //!!!!!!!
void Set();
void Show();
};
class Singer:public Worker
{
protected:
enum{other,alto,contralto,soprano,bass,baritone,tenor};
enum{Vtypes=7};
private:
static char *pv[Vtypes];
int voice;
public:
Singer():Worker(),voice(other){}
Singer(const string &s,long n,int v=other):Worker(s,n),voice(v){}
Singer(const Worker &wk,int v=other):Worker(wk),voice(v){}
void Set();
void Show();
};
#endif WORKER_H_
#include<iostream>
#include"worker0.h"
using namespace std;
Worker::~Worker()
{}
void Worker::Set()
{
cout<<"Enter name of Worker:";
getline(cin,fullname);//使用getline()可以输入带有空格的字符串。
cout<<"Enter id of Worker:";
cin>>id;
while(cin.get()!='\n') //一般要与getline()同时使用。
continue;
}
void Worker::Show()
{
cout<<"Name:"<<fullname<<endl;
cout<<"Id:"<<id<<endl;
}
void Waiter::Set()
{
Worker::Set(); //派生类无法直接访问基类私有成员 可以通过调用基类的公有成员函数来访问。
cout<<"Enter panache of waiter:";
cin>>panache;
while(cin.get()!='\n')
continue;
}
void Waiter::Show()
{
cout<<"Category waiter:\n";
Worker::Show();
cout<<"Panache:"<<panache<<endl;
}
char *Singer::pv[]={"other","alto","contralto","soprano","bass","baritone","tenor"};//?????????
void Singer::Set()
{
Worker::Set();
cout<<"Enter number for singer's vocal range:\n ";
int i;
for(i=0;i<Vtypes;i++)
{
cout<<i<<":"<<pv[i]<<" ";
if(i%4==3)
cout<<endl;
}
if(i%4!=0)
cout<<endl;
cin>>voice;
while(cin.get()!='\n')
continue;
}
void Singer::Show()
{
cout<<"Category:singer\n";
Worker::Show();
cout<<"Vocal range:"<<pv[voice]<<endl;
}
#include<iostream>
#include"worker0.h"
using namespace std;
const int N=4;
int main()
{
Waiter Bob("Bob Apple",314L,5);
Singer Bev("Beverly HIlls",522L,3);
Waiter w_temp;
Singer s_temp;
Worker *pw[N]={&Bob,&Bev,&w_temp,&s_temp};
int i;
for(i=2;i<N;i++)
{
pw[i]->Set();
}
for(i=0;i<N;i++)
{
pw[i]->Show();
cout<<endl;
}
return 0;
}
2.虚基类使得从多个类(它们的基类相同)派生出的对象只继承一个基类对象。使用关键字virtual。
#ifndef WORKERMI_H_
#define WORKERMI_H_
#include<string>
using namespace std;
class Worker
{
private:
string fullname;
long id;
public:
Worker(const string &s="none",long n=0);
virtual ~Worker()=0;
virtual void data();//输出共有部分
virtual void get();//输入共有部分
virtual void set()=0;//调用data(),并输入特有部分
virtual void show()=0;//调用get(),并输出特有部分
};
class Waiter:virtual public Worker
{
private:
int panache;
public:
Waiter(const string &s="none",long n=0,int p=0);
Waiter(const Worker &wk,int p=0);
void data();
void get();
void set();
void show();
};
class Singer:virtual public Worker
{
protected:
enum{other,alto,contralto,soprano,base,baritone,tenor};//分别为0,1,2,3,4,5,6
enum{Vtypes=7};
private:
static char *pv[Vtypes];
int voice;
public:
Singer(const string &s="none",long n=0,int v=other);
Singer(const Worker &wk,int v=other);
void data();
void get();
void set();
void show();
};
class SingerWaiter:public Singer,public Waiter
{
public:
//SingerWaiter();
SingerWaiter(const string &s="none",long n=0,int p=0,int v=other);
SingerWaiter(const Worker &wk,int p=0,int v=other);
void data();
void get();
void set();
void show();
};
#endif WORKERMI_H_
#include<iostream>
#include"workmi.h"
using namespace std;
Worker::Worker(const string &s,long n)
{
fullname=s;
id=n;
}
Worker::~Worker()
{}
void Worker::data() //输出共有部分的数据
{
cout<<"Name: "<<fullname<<endl;
cout<<"Id: "<<id<<endl;
}
void Worker::get() //输入共有部分的数据
{
//cout<<"Enter Worker's Name:";
getline(cin,fullname);
cout<<"Enter Worker's Id:";
cin>>id;
while(cin.get()!='\n')
continue;
}
Waiter::Waiter(const string &s,long n,int p):Worker(s,n)
{
panache=p;
}
Waiter::Waiter(const Worker &wk,int p):Worker(wk)
{
panache=p;
}
void Waiter::set()
{
cout<<"Enter Waiter's name:";
Worker::get(); //输入共有部分的数据
get(); // 输入自身特有数据
}
void Waiter::get()
{
cout<<"Enter Waiter's panache:";
cin>>panache;
}
void Waiter::data()
{
cout<<"Panache:"<<panache<<endl;
}
void Waiter::show()
{
cout<<"Category:waiter\n";
Worker::data();
data();
}
Singer::Singer(const string &s,long n,int v):Worker(s,n)
{
voice=v;
}
Singer::Singer(const Worker &wk,int v):Worker(wk)
{
voice=v;
}
char *Singer::pv[]={"other","alto","contralto","soprano","bass","baritone","tenor"};//?????????
void Singer::set()
{
cout<<"Enter Singer's name:";
Worker::get(); //输入共有部分的数据
get(); // 输入自身特有数据
}
void Singer::get()
{
cout<<"Enter Singer's number of vocal range:\n";
int i;
for(i=0;i<Vtypes;i++)
{
cout<<i<<":"<<pv[i]<<" ";
if(i%4==3)
cout<<endl;
}
if(i%4!=0)
cout<<endl;//输出数组 提供选择
cin>>voice; //输入选择第几个
}
void Singer::data()
{
cout<<"Voice:"<<pv[voice]<<endl;
}
void Singer::show()
{
cout<<"Category:singer\n";
Worker::data();
data();
}
SingerWaiter::SingerWaiter(const string &s,long n,int p,int v):Worker(s,n),Waiter(s,n,p),Singer(s,n,v)
{}
SingerWaiter::SingerWaiter(const Worker &wk,int p,int v):Worker(wk),Waiter(wk,p),Singer(wk,v)
{}
void SingerWaiter::data()
{
//Worker::data();
Singer::data();
Waiter::data();
}
void SingerWaiter::get()
{
Singer::get();
Waiter::get();
}
void SingerWaiter::set()
{
cout<<"Enter singerwaiter's name:";
Worker::get();
get();
}
void SingerWaiter::show()
{
cout<<"Category singerwaiter:\n";
Worker::data();
data();
}
#include<iostream>
#include"workmi.h"
#include<cstring>
using namespace std;
const int N=2;
int main()
{
Worker *lolas[N];
int ct;
for(ct=0;ct<N;ct++)
{
char choice;
cout<<"Enter the employee category:\n"<<"w:waiter s:singer t:singerwaiter q:quit\n";
cin>>choice;
while(strchr("wstq",choice)==NULL)//一定要大写才行
{
cout<<"Please enter a w s t q:";
cin>>choice;
}
if(choice=='q')
break;
switch(choice)
{
case 'w':lolas[ct]=new Waiter;
break;
case 's':lolas[ct]=new Singer;
break;
case 't':lolas[ct]=new SingerWaiter;
break;
}
cin.get();
lolas[ct]->set();
}
cout<<"\nHere is your staff:\n";
int i;
for(i=0;i<ct;i++)
{
cout<<endl;
lolas[i]->show();
}
for(i=0;i<ct;i++)
delete lolas[i];
cout<<"Bye!";
return 0;
}
3.模板类
#ifndef STACKTP_H_
#define STACKTP_H_
template<typename Type>
class Stack
{
private:
enum {MAX=10};
Type items[MAX];
int top;
public:
Stack();
bool isempty();
bool isfull();
bool push(const Type &item);
bool pop(Type &item);
};
template <typename Type>
Stack<Type>::Stack()
{
top=0;
}
template<typename Type>
bool Stack<Type>::isempty()
{
return top==0;
}
template<typename Type>
bool Stack<Type>::isfull()
{
return top==MAX;
}
template<typename Type>
bool Stack<Type>::push(const Type &item)
{
if(top<MAX)
{
items[top++]=item;
return true;
}
else
return false;
}
template<typename Type>
bool Stack<Type>::pop(Type &item)
{
if(top>0)
{
item=items[--top];
return true;
}
else
return false;
}
#endif STACKTP_H_
#include<iostream>
#include<string>
#include<cctype>
#include"stacktp.h"
using namespace std;
int main()
{
Stack<string> st;
char ch;
string s;
cout<<"Enter A to add,P to pop,Q to quit:\n";
while(cin>>ch&&toupper(ch)!='Q')
{
while(cin.get()!='\n')
continue;//消除无用的字符
switch(ch)
{
case 'A':
case 'a':
if(st.isfull())
cout<<"Stack is full!\n";
else
{ cout<<"Enter a string:";
getline(cin,s);
// cin>>s; 不能输入带有空格的字符串 cin>>s 只能读取一个不带空格的字符串
st.push(s);
cout<<"push sucessfully!\n";
}
break;
case 'p':
case 'P':
if(st.isempty())
cout<<"Stack is empty!\n";
else
{ st.pop(s);
cout<<"The string poped is:"<<s<<endl;
}
break;
}
cout<<"Enter A to add,P to pop,Q to quit:\n";
}
cout<<"Bye!\n";
return 0;
}
4.ArrayTP<ArrayTP<int ,5>,10> twodeep;
相当于一个二维的数组 twodeep[i][j];
5.使用多个类型参数的模板类
#include<iostream>
#include<string>
using namespace std;
template<typename T1,typename T2>
class Pair
{
private:
T1 a;
T2 b;
public:
Pair(const T1 &ta,const T2 &tb)
{
a=ta;
b=tb;
}
T1 &geta() //引用类型则是可修改的左值 可以进行修改
{return a;}
T2 &getb()
{return b;}
};
int main()
{
Pair<string,int> rating[4]=
{
Pair<string,int>("yan",5), //类名为Pair<string,int>
Pair<string,int>("wang",4),
Pair<string,int>("su",3),
Pair<string,int>("cao",2)
};
int n=sizeof(rating)/sizeof(Pair<string,int>);
for(int i=0;i<n;i++)
{
cout<<rating[i].getb()<<": "<<rating[i].geta()<<endl;
}
rating[3].getb()=8;
rating[3].geta()="hahha";
cout<<rating[3].getb()<<": "<<rating[3].geta()<<endl;
return 0;
}