You are not allowed to perform this action
cpp:example1
國立屏東商業技術學院 資訊工程系 物件導向程式設計
1. 實例演練
本節以cpp.hw2第二題為例,改以類別方式來實作,
- 物件指標陣列
- 成員函式多載
- istream
- ifstream
- string類別
- stringstream類別與數值轉換
請先參考下面的程式碼:
#include <iostream>
#include <string>
using namespace std;
#ifndef _NAME_
#define _NAME_
class Name
{
private:
string firstname;
string lastname;
public:
Name();
Name(string n);
void set_firstname(string fn);
string get_firstname();
void set_lastname(string ln);
string get_lastname();
void show();
};
#endif
#include "name.h"
Name::Name()
{
}
Name::Name(string n)
{
unsigned pos=n.find(" ");
firstname = n.substr(0,pos);
lastname = n.substr(pos+1,n.size()-firstname.size());
}
void Name::set_firstname(string fn)
{
firstname=fn;
}
string Name::get_firstname()
{
return firstname;
};
void Name::set_lastname(string ln)
{
lastname=ln;
}
string Name::get_lastname()
{
return lastname;
}
void Name::show()
{
cout << firstname << " " << lastname << endl;
}
上面這兩個檔案分別是「Name」類別的定義與實作。下面則是「Member」類別的定義與實作:
#ifndef _MEMBER_
#define _MEMBER_
#include "name.h"
enum Program {Gold, Silver};
class Member
{
private:
Name *name;
string phone;
Program memberProgram;
union
{
double discount;
int freeMinute;
} benefit;
public:
void showInfo();
void setPhone(string str);
Name *getName();
void setName(Name *n);
void setProgram(Program p);
void setBenefit(int f);
void setBenefit(double d);
};
#endif
#include "member.h"
#include "name.h"
void Member::showInfo()
{
name->show();
cout << phone << " ";
if(memberProgram==Gold)
{
cout << "Gold" << " " << benefit.discount << endl;
}
else
{
cout << "Silver" << " " << benefit.freeMinute << endl;
}
}
void Member::setPhone(string str)
{
phone = str;
}
Name * Member::getName()
{
return name;
}
void Member::setName(Name *n)
{
name = n;
}
void Member::setProgram(Program p)
{
memberProgram = p;
}
void Member::setBenefit(int f)
{
benefit.freeMinute = f;
}
void Member::setBenefit(double d)
{
benefit.discount = d;
}
我們打算設計一個類別「DataGetter」用以取得使用者輸入的資料:
#include <iostream>
#include <istream>
#include <sstream>
#include <string>
#include "member.h"
using namespace std;
#ifndef _DATA_GETTER_
#define _DATA_GETTER_
class DataGetter
{
public:
string getAString(istream &is);
Member *getMemberData(istream &is);
};
#endif
在這個定義中,我們設計了兩個成員函式,用以取得一個字串以及取得會員資料。在設計上,這兩個函式都有一個參數「istream &is」,可以配合cin或是檔案的物件來進行資料的存取,其實作如下:
#include "dataGetter.h"
#include "member.h"
string DataGetter::getAString(istream &is)
{
string str;
getline(is, str);
return str;
}
Member * DataGetter::getMemberData(istream &is)
{
Member *newMember=new Member;
string str;
getline(is, str);
newMember->setName(new Name(str));
getline(is, str);
newMember->setPhone(str);
getline(is, str);
if(str.compare("Gold")==0)
{
newMember->setProgram(Gold);
getline(is, str);
double discount;
stringstream convert;
convert << str;
if(!(convert >> discount))
discount=0.0;
newMember->setBenefit(discount);
}
else if(str.compare("Silver")==0)
{
newMember->setProgram(Silver);
getline(is, str);
int freeMinute;
stringstream convert;
convert << str;
if(!(convert>> freeMinute))
freeMinute=0;
newMember->setBenefit(freeMinute);
}
return newMember;
}
在上述的實作中,我們使用了定義在「<sstream>」中的,「stringstream」來進行字串與數值間的轉換。現在讓我們來看看,如何使用上述的類別來實作cpp.hw2:
#include <iostream>
#include <fstream>
#include "member.h"
#include "dataGetter.h"
using namespace std;
typedef Member* Members;
int main()
{
Members *members = new Members[5];
DataGetter *dg = new DataGetter;
ifstream fin("members.dat");
for(int i=0;i<5;i++)
{
members[i] = dg->getMemberData(fin);
}
fin.close();
cout << "Input: ";
string findName = dg->getAString(cin);
bool found=false;
while(findName.compare("Quit")!=0)
{
for(int i=0;i<5;i++)
{
if(((members[i]->getName())->get_lastname()).compare(findName)==0)
{
members[i]->showInfo();
found=true;
}
}
if(!found)
cout << "Member not found!" << endl;
found=false;
cout << "Input: ";
findName = dg->getAString(cin);
}
cout << "Bye" << endl;
delete [] members;
}
在「main.cpp」的實作中,我們先以
ifstream fin("members.dat");
「ifstream」是定義在「<fstream>」中,我們用以開啟members.dat檔案,其檔案內容如下:
Jun Wu 0912345678 Gold 0.8 Ming-Chung Liu 0988123456 Silver 100 Cho-Ming Kuo 0999999999 Silver 80 Sing-Shi Chang 0933444555 Gold 0.95 Ping Kuo 0955333222 Gold 0.9
我們利用「DataGetter」類別來取得使用者輸入的資料:
DataGetter *dg = new DataGetter;
所取得的資料將會放在我們所建立的存放會員物件的陣列:
typedef Member* Members; Members *members = new Members[5];
在使用「getMemberData()」成員函式時,我們是以「fin」做為參數來透過檔案存取資料:
for(int i=0;i<5;i++) { members[i] = dg->getMemberData(fin); } fin.close();
最後,我們以下面的程式碼,完成程式所需的處理:
cout << "Input: "; string findName = dg->getAString(cin); bool found=false; while(findName.compare("Quit")!=0) { for(int i=0;i<5;i++) { if(((members[i]->getName())->get_lastname()).compare(findName)==0) { members[i]->showInfo(); found=true; } } if(!found) cout << "Member not found!" << endl; found=false; cout << "Input: "; findName = dg->getAString(cin); } cout << "Bye" << endl; delete [] members;
本實例的Makefile如下:
all: dataGetter.o name.o member.o
g++ main.cpp name.o member.o dataGetter.o -o main
dataGetter.o: dataGetter.cpp dataGetter.h
g++ -c dataGetter.cpp
name.o: name.cpp name.h
g++ -c name.cpp
member.o: member.cpp member.h
g++ -c member.cpp
clean:
rm -f *.o main *.*~ *~
cpp/example1.txt · 上一次變更: 2019/07/02 15:01 (外部編輯)
