Tải bản đầy đủ (.doc) (21 trang)

Ôn thi Lập trình hướng đối tượng

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (140.83 KB, 21 trang )

Tập tin - thư mục
Xét bài toán sau:

Thư mục chứa các phần tử, phần tử có hai loại là tập tin và thư mục
Lớp phần tử: là một lớp thuần ảo nhờ có cái đặt thao tác getSize khơng cần định nghĩa.
class Element
{
protected:
String m_name;
double m_size;
public:
Element(const char *n="New",const double s=0);
virtual ~Element();
virtual void Input();
virtual void Output() const;
virtual double getSize() const = 0;
virtual String getClass() const
{return "Element";}
};

Element::Element(const char *n, const double s) :m_name(n),m_size(s){}
void Element::Input()
{
cout<<"Nhap ten: ";cin>>m_name;
}
void Element::Output() const
{
cout<}
Element::~Element()
{}



1


Thao tác khởi tạo, nhập, xuất của phần tử chủ yếu cho các lớp thư mục và tập tin thừa kế, bản thân lớp
thuần ảo không thể tạo đối tượng.
Lớp tập tin:
class File :public Element
{
public:
File(const char *n="NewFile",const double s=0);
virtual void Input();
virtual void Output() const;
virtual double getSize() const;
virtual String getClass() const
{return "File";}
};

File::File(const char *n, const double s) :Element(n,s){}
void File::Input()
{
Element::Input();
cout<<"Nhap kich thuoc: ";
cin>>m_size;cin.ignore();
}
void File::Output() const
{
Element::Output();
cout<<"\tSize: "<}

double File::getSize() const
{
return m_size;
}
Lớp tập tin định nghĩa lại các thao tác vì sử dụng thuộc tính m_size
Lớp thư mục
Đặc trưng của quan hệ chứa là có một danh sách các phần tử và có thao tác thêm phần tử vào danh
sách.
Thao tác thêm một phần tử có kiễu trả về là chính nó, để có thể quản lý dễ dàng.
class Folder : public Element

2


{
protected:
ArrayTemp<Element*,30> m_ListElement;
public:
Folder(const char *n = "NewFolder");
virtual ~Folder();
virtual void Input();
virtual void Output() const;
virtual double getSize() const;
void OutputFull() const;
Element* Add(Element *e);
virtual String getClass()const{return "Folder";}
};

Folder::Folder(const char *n):Element(n){}
Element* Folder::Add(Element *e)

{
if(m_ListElement.isFull() || e == NULL)
return NULL;
m_ListElement.Insert(e) ;
return e;
}
Folder::~Folder()
{
for(int i=0; idelete m_ListElement[i];
}
void Folder::Output() const
{
Element::Output();cout<<"\t<DIR>";
}
Thao tác nhập một thư mục, ta cho người dùng nhập vào tên thư mục (thao tác này cho kế thừa từ lớp
phần tử)
Sau đó hỏi người dùng có nhập con của thư mục vừa tạo khơng?
Nếu có thì hỏi là nhập thư mục hay là tập tin.
Vậy cứ mỗi lần chọn tạo thư mục thì sẽ xuất hiện menu chọn tạo tập tin hay tạo thư mục
void Folder::Input()

3


{
Element::Input();
char c;
while(1)
{

cout<<"Tao phan tu con(c/k) ?";
cin>>c;cin.ignore();
if(c == 'k' || c == 'K') return;
else
{
int chon;Element *pEle;
while(1)
{
system("cls");
cout<<"1.Tao tap tin\n"
<<"2.Tao thu muc\n"
<<"0.Thoat\n";
cout<<"Chon=";cin>>chon;cin.ignore();
switch(chon)
{
case 1:pEle = new File;break;
case 2:pEle = new Folder;break;
case 0:return;
}
if(pEle)
{
pEle->Input();
Add(pEle);
}
}
}
}
}
Ta thấy rằng, ta chỉ cần gọi thao tác, ứng với mỗi đối tượng sẽ tự động thực hiện nhiệm vụ của nó - đây
là cốt lõi của bài tốn đa hình

Thao tác xuất các con trong một thư mục (bao gồm thư mục và tập tin), ta duyệt qua danh sách và bảo
các phần tử xuất
void Folder::OutputFull() const

4


{
Element::Output();
for(int i=0; i{
cout<<"\n\t";m_ListElement[i]->Output();
}
}
Taị lớp ứng dụng, ta chỉ cần tạo một thư mục chứa (root)
class Application
{
Folder *m_pRoot;
void VanHanh();
void Tao();
void Xem();
public:
Application();
~Application();
};
Nhờ cài đặt thao tác thêm phần tử có kiễu trả về là chính con trỏ trỏ tới đối tượng vừa thêm, ta sẽ quản lý
nó : thêm tiếp phần tử con
Application::Application()
{
m_pRoot = new Folder("Root");

Folder *pChild = (Folder*)m_pRoot->Add(new Folder("TM1"));
pChild->Add(new File("F11",15));
pChild = (Folder*)m_pRoot->Add(new Folder("TM2"));
pChild->Add(new File("F21",12));
pChild->Add(new File("F22",15));
m_pRoot->Add(new File("F0",5));
VanHanh();
}
void Application::VanHanh()
{
int chon;
while(1)

5


{
system("cls");
cout<<"1.Tao\n"
<<"2.Xem\n"
<<"0.Thoat\n";
cout<<"Chon=";cin>>chon;cin.ignore();
switch(chon)
{
case 1:Tao();break;
case 2:Xem();break;
case 0:return;
}
}
}

void Application::Tao()
{
int chon;Element *pEle;
while(1)
{
system("cls");
cout<<"1.Tao tap tin\n"
<<"2.Tao thu muc\n"
<<"0.Thoat\n";
cout<<"Chon=";cin>>chon;cin.ignore();
switch(chon)
{
case 1:pEle = new File;break;
case 2:pEle = new Folder;break;
case 0:return;
}
if(pEle)
{
pEle->Input();
m_pRoot->Add(pEle);
}
}
}

6


Taị menu chọn Xem, xem các phần tử bên torng thư mục Root
m_pRoot->OutputFull();
Tính kích thước các phần tử, nếu là thư mục thì tính tổng các tập tin bên trong nó

cout<<m_pRoot->getSize()
Đây là thao tác cài đặt trong Folder.cpp
double Folder::getSize() const
{
double sum = 0;
for(int i=0; i < m_ListElement.getLength();i++)
sum += m_ListElement[i]->getSize();
return sum;
}

7


Toán tử - toán hạng

Một biểu thức gồm hai toán hạng, tốn hạng thì có thể là biểu thức, hằng số, biến số
lớp Toán hạng
class ToanHang
{
public:
ToanHang(){}
virtual void Nhap(){}
virtual void Xuat() const {}
virtual bool InstanceOf(const char *ch)
{return ch=="ToanHang";}
};
Lớp Hằng
class Hang:public ToanHang
{
protected:

double m_Tri;
public:
Hang(){}
virtual void Nhap(){cout<<"Nhap tri : ";cin>>m_Tri;}
virtual void Xuat() const{cout<virtual bool InstanceOf(const char *ch)
{return (ch=="Hang"||ToanHang::InstanceOf(ch));}
};
Lớp Biến

8


class Bien:public ToanHang
{
protected:
String m_Ten;
public:
Bien(){}
virtual void Nhap()
{cout<<"Nhap bien : ";cin>>m_Ten;}
virtual void Xuat() const{cout<virtual bool InstanceOf(const char *ch)
{return (ch=="Bien"||ToanHang::InstanceOf(ch));}
};
Lớp Biểu thức
class BieuThuc:public ToanHang
{
protected:
char m_TTu;

ToanHang *pTh1,*pTh2;
public:
BieuThuc(){}
~BieuThuc(){delete pTh1;delete pTh2;}
virtual void Nhap();
virtual void Xuat() const;
virtual bool InstanceOf(const char *ch)
{return (ch=="BieuThuc"||ToanHang::InstanceOf(ch));}
int ThongKeBien() const;
int ThongKeHang() const;
};

9


void BieuThuc::Nhap()
{
ToanHang *th;
int chon;
cout<<"Nhap toan hang 1 cua bieu thuc\n";
cout<<"1.Nhap bieu thuc\n"
<<"2.Nhap bien\n"
<<"3.Nhap hang\n";
cin>>chon;cin.ignore();
switch(chon)
{
case 1:th = new BieuThuc;break;
case 2:th = new Bien;break;
case 3:th = new Hang;break;
}

if(th)
{
th->Nhap();pTh1 = th;
}
cout<<"Nhap toan hang 2 cua bieu thuc\n";
cout<<"1.Nhap bieu thuc\n"
<<"2.Nhap bien\n"
<<"3.Nhap hang\n";
cin>>chon;cin.ignore();
switch(chon)
{
case 1:th = new BieuThuc;break;
case 2:th = new Bien;break;
case 3:th = new Hang;break;
}
if(th)
{
th->Nhap();pTh2 = th;
}
cout<<"Nhap toan tu : ";cin>>m_TTu;
}

10


void BieuThuc::Xuat() const
{
cout<<"(";
pTh1->Xuat();cout<<m_TTu;pTh2->Xuat();
cout<<")";

}
int BieuThuc::ThongKeBien() const
{
int bien = 0;
if(pTh1->InstanceOf("Bien")) bien++;
else if(pTh1->InstanceOf("BieuThuc"))
bien+=((BieuThuc*)pTh1)->ThongKeBien();
if(pTh2->InstanceOf("Bien")) bien++;
else if(pTh2->InstanceOf("BieuThuc"))
bien+=((BieuThuc*)pTh2)->ThongKeBien();
return bien;
}
int BieuThuc::ThongKeHang() const
{
int hang = 0;
if(pTh1->InstanceOf("Hang")) hang++;
else if(pTh1->InstanceOf("BieuThuc"))
hang+=((BieuThuc*)pTh1)->ThongKeHang();
if(pTh2->InstanceOf("Hang")) hang++;
else if(pTh2->InstanceOf("BieuThuc"))
hang+=((BieuThuc*)pTh2)->ThongKeHang();
return hang;
}

11


class UngDung
{
protected:

BieuThuc *bt;
void VanHanh();
void Nhap();
void Xuat() const;
public:
UngDung(){bt = new BieuThuc;VanHanh();}
~UngDung(){delete bt;}
};
void UngDung::VanHanh()
{
int chon;
while(1)
{
system("cls");
cout<<"1.Nhap\n"
<<"2.Xem\n"
<<"0.Thoat\n";
cin>>chon;cin.ignore();
switch(chon)
{
case 1:Nhap();break;
case 2:Xuat();break;
case 0:return;
}
}
}
void UngDung::Nhap()
{
ToanHang *th = new BieuThuc();
th->Nhap();

bt = (BieuThuc*)th;
}

12


void UngDung::Xuat() const
{
int chon;
while(1)
{
system("cls");
cout<<"1.Xem bieu thuc\n"
<<"2.Thong ke\n"
<<"0.Thoat\n";
cin>>chon;cin.ignore();
switch(chon)
{
case 1:bt->Xuat();cin.get();break;
case 2:
cout<<"Bien : "
<<bt->ThongKeBien();cout<cout<<"Hang : "
<<bt->ThongKeHang();cin.get();cout<break;
case 0:return;
}
}
}


13


Thủ đơ - thành phố

Một quốc gia có nhiều thành phố, một thành phố chỉ thuộc một quốc gia
Để miêu tả một quốc gia có nhiều thành phố khác với mối quan hệ chứa, ta có danh sách các con trỏ:
class ThanhPho;
class QuocGia
{
protected:
ArrayTemp<ThanhPho*,30> * m_dsTP;
String m_tenQG;
public:
QuocGia(const char* t = "");
~QuocGia();
bool CapNhatTP(ThanhPho* pTP);
const String& TenQG()const{return m_tenQG;}
void Nhap();
void Xuat() const;
};
Thao tác PTTL của QuocGia là khởi tạo con trỏ tới danh sách con trỏ
QuocGia::QuocGia(const char *t):m_tenQG(t)
{
m_dsTP = new ArrayTemp<ThanhPho*,30>;
}
Thao tác hủy một con trỏ
QuocGia::~QuocGia()
{
delete m_dsTP;

}
void QuocGia::Nhap()
{
cout<<"Nhap ten Quoc Gia : ";cin>>m_tenQG;
}

14


Thao tác thêm một Thành phố vào trong danh sách con trỏ của QuocGia là một thao tác mang ý nghĩa
hai chiều, sau khi thêm thành công, con trỏ trỏ tới ThanhPho sẽ gọi hàm CapNhatQuocGia để cho con trỏ
của ThanhPho trỏ tới bản thân QuocGia này
Thao tác chính:
bool kq = m_dsTP->Insert(pTP);
if(kq) pTP->CapNhatQG(this);
bool QuocGia::CapNhatTP(ThanhPho* pTP)
{
if(pTP == NULL) return false;
for(int i = 0; i < m_dsTP->getLength();i++)
if((*m_dsTP)[i]->TenTP() == pTP->TenTP())

//phai include ThanhPho

return false;
bool kq = m_dsTP->Insert(pTP);
if(kq) pTP->CapNhatQG(this);
return kq;
}
Thao tác phụ trợ : duyệt danh sách xem đã có phần tử trùng tên chưa.
vì m_dsTP là một con trỏ nên để truy cập tới bản thân đối tượng đang xét ta dùng (*m_dsTP)[i]->TenTP()

Thao tác xuất, xuất tên QuocGia và xuất Tên thành phố trong danh sách
void QuocGia::Xuat() const
{
cout<if(m_dsTP->getLength()>0)
{
cout<<"\t- Co cac thanh pho -\n";
for(int i = 0;i < m_dsTP->getLength();i++)
{
cout<<"\t"<<(*m_dsTP)[i]->TenTP();
cout<}
}
}

15


Lớp ThanhPho include QuocGia, vì vậy nên trong QuocGia ta chỉ khai báo trước tên class chứ không
include.
#include "QuocGia.h"
class ThanhPho
{
protected:
String m_tenTP;
QuocGia* m_pQG;
public:
ThanhPho(const char* t = "",QuocGia* pQG = NULL);
~ThanhPho(){}
const String& TenTP() const{return m_tenTP;}

void CapNhatQG(QuocGia* pQG);
void Nhap();
void Xuat() const;
};
Thao tác PTTL của ThanhPho, cho m_pQG = NULL, và dùng con trỏ pQG->CapNhatTP(this), trong hàm
này sẽ gọi tới hàm pTP -> CapNhatQG, trong này thì ta sẽ cho m_pQG = pQG
ThanhPho::ThanhPho(const char* t,QuocGia* pQG) :m_tenTP(t),m_pQG(NULL)
{
if(pQG)
pQG->CapNhatTP(this);
}
void ThanhPho::CapNhatQG(QuocGia* pQG)
{
m_pQG = pQG;
}
void ThanhPho::Nhap()
{
cout<<"Nhap ten TP : ";cin>>m_tenTP;
}
void ThanhPho::Xuat() const
{
cout<if(m_pQG) cout<<"\tThuoc quoc gia : "<<m_pQG->TenQG();
cout<}

16


class UngDung

{
ArrayTemp<QuocGia*,20> m_dsQG;
ArrayTemp<ThanhPho*,30> m_dsTP;
public:
UngDung();
~UngDung();
private:
void VanHanh();
void Nhap();
void Xuat() const;
void CapNhatLienKet();
QuocGia* TimQG(const char* ten)const;
ThanhPho* TimTP(const char* ten)const;
};
UngDung::UngDung()
{
const char* tenQG[] = {"Anh","Phap","TayBanNha","Y"};
const int numQG = sizeof(tenQG)/sizeof(tenQG[0]);
for(int i = 0; i < numQG ; i++)
m_dsQG.Insert(new QuocGia(tenQG[i]));
const char* tenTP[] = {"LonDon","Paris","Barca","Milan"};
const int numTP = sizeof(tenTP)/sizeof(tenTP[0]);
for(int i = 0; i < numTP ; i++)
m_dsTP.Insert(new ThanhPho(tenTP[i]));
VanHanh();
}
UngDung::~UngDung()
{
for(int i = 0;i < m_dsQG.getLength();i++)
delete m_dsQG[i];

for(int i = 0;i < m_dsTP.getLength();i++)
delete m_dsTP[i];
}

17


void UngDung::VanHanh()
{
int chon;
while(1)
{
system("cls");
cout<<"1.Nhap\n"
<<"2.Xuat\n"
<<"3.Cap nhat lien ket\n"
<<"0.Thoat\n";
cout<<"Chon : ";cin>>chon;cin.ignore();
switch(chon)
{
case 1:Nhap();break;
case 2:Xuat();break;
case 3:CapNhatLienKet();break;
case 0:return;
}
}
}
void UngDung::Nhap()
{
int chon;QuocGia* pQG;ThanhPho* pTP;

while(1)
{
system("cls");
cout<<"1.Nhap quoc gia moi\n"
<<"2.Nhap thanh pho moi\n"
<<"0.Thoat\n";
cout<<"Chon : ";cin>>chon;cin.ignore();
switch(chon)
{
case 1:
pQG = new QuocGia;
pQG->Nhap();
m_dsQG.Insert(pQG);
break;
case 2:

18


pTP = new ThanhPho;
pTP->Nhap();
m_dsTP.Insert(pTP);
break;
case 0:return;
}
}
}
void UngDung::Xuat() const
{
int chon;QuocGia* pQG;ThanhPho* pTP;

while(1)
{
system("cls");
cout<<"1.Xuat quoc gia\n"
<<"2.Xuat thanh pho\n"
<<"0.Thoat\n";
cout<<"Chon : ";cin>>chon;cin.ignore();
switch(chon)
{
case 1:
for(int i = 0;i < m_dsQG.getLength();i++)
m_dsQG[i]->Xuat();
cin.get();
break;
case 2:
for(int i = 0;i < m_dsTP.getLength();i++)
m_dsTP[i]->Xuat();
cin.get();
break;
case 0:return;
}
}
}

19


void UngDung::CapNhatLienKet()
{
String tenqg;char chon;

cout<<"Nhap ten Quoc Gia : ";cin>>tenqg;
QuocGia* pQG = TimQG(tenqg);
if(pQG)
{
do
{
String tentp;
cout<<"Nhap ten Thanh pho : ";cin>>tentp;
ThanhPho* pTP = TimTP(tentp);
if(pTP)
{
pQG->CapNhatTP(pTP);
}
else
{
cout<<"khong tim thay thanh pho co ten : "<cout<<"co muon tao moi thanh pho co ten : "<
(c/k)";

cin>>chon;cin.ignore();
if(chon == 'c' || chon == 'C')
{
pTP = new ThanhPho(tentp,pQG);
m_dsTP.Insert(pTP);
}
}
cout<<"\nTiep tuc khong ? (c/k)";
cin>>chon;cin.ignore();
}while(chon == 'c' || chon == 'C');

}
else
cout<<"Khong co quoc gia : "<}
QuocGia* UngDung::TimQG(const char *ten) const

20



×