第一次作業(yè)
這個作業(yè)將讓你去練習建立一些簡單的類和使用C++的基本功能,包括:?封裝,引用,動態(tài)內(nèi)存開辟,簡單構(gòu)造函數(shù)和析構(gòu)函數(shù)和const.
這個程序片段未??供編或調(diào)試.做出合理的錯誤修正事你任務(wù)的一部分,或要求在類里明.
一般的,我們會給你最基本部分的代碼.如果你需要它們,你總是可以在一個類里添加額外的變量或方法.這個作業(yè)被分為三個部分來顯示了如何工作.
1.設(shè)計要求
第一部分)?構(gòu)建簡單的類
R1.1)?創(chuàng)建一個Person類,其模型在下面的代碼結(jié)構(gòu)里.
R1.2)?人類(Persons)應(yīng)該有一些屬性: name, email_address, birthdate as作為表示下面類(的屬性)的??述.
R1.3)?按下面的要求創(chuàng)建一個Date類.
R1.4)?每個類都應(yīng)該有一個按<<運算符的輸出的Print函數(shù).這個函數(shù)應(yīng)該??供打印這個類的文本表示,用cout或其他流.
這些是非常簡單的C++的類,它們的變量不是對象,但是只是C++部分的
內(nèi)在類型.而且這個變量既不是值或指針(它們也不是引用).
//file Date.h
class?Date{
public:
? ? ? ?Date();
? ? ? ?Date( int year, int month, int day );...
private:
? ? ? ?int _year;
? ? ? ?int _month;
? ? ? ?int _day;
};
//end file Date.h
//filePerson.h
class Person{
public:
? ? ? ?Person(void);
? ? ? ?Person(char * their_name, char * email, int day, int month, int year);char * GetName();
? ? ? ?char * GetEmailAddress();
? ? ? ?Date GetBirthDate();
? ? ? ?void Print();
private:
? ? ? ?char* name;
? ? ? ?char* email_address;
? ? ? ?Date date;
};
//end file Person.h
第二部分)構(gòu)建一個容器類Set container.
R2.1) 建立一個set的模型PersonSet類,并且它只能保存Person的對象.
R2.2) 這個set應(yīng)該存儲person的地址(指針),以便可以獲取原始對象(非
拷貝).
R2.3) set的存儲應(yīng)該用動態(tài)數(shù)組來保存Person的指針(用new來創(chuàng)建),但是set不應(yīng)該有界限(數(shù)組大小),它們應(yīng)該在成員進行添加或移除時,適當進行擴展..
R2.4) 成員不按任何特定順序存儲(無排序).
R2.5) set允許存儲副本(相同對象).
R2.6) Add()函數(shù)應(yīng)該當在添加的時候,并且需要的情況,進行擴展數(shù)組大小并且輸出一串信息.
R2.7) Remove()函數(shù)應(yīng)該在移除的時候,并且在需要的情況,可以進行縮小數(shù)組大小并輸出一串信息.
R2.8) Add()函數(shù)應(yīng)該帶一個引用類型的參數(shù)(Person&).
R2.9) 迭代應(yīng)該通過NextElement()函數(shù)來??供.
R2.10) NextElement()和RemoveElement()應(yīng)該通過引用返回
對于現(xiàn)在我們將去建立sets去只保存Person對象,因此類名是personSet
//file PersonSet.h
class PersonSet{
public:
//default constructor allocate appropriate heap storage store elements on
//heap array declared like this: new Person*[initial_size];
? ? ? ?PersonSet (int initial_size = 4);
//store element in the set if the set is full allocate more memory
? ? ? ?~ PersonSet (void);
public:
? ? ? ?void Add(Person & element) ;
? ? ? ?Person & NextElement() ;
//從set中移除最后一個成員
//如果Set空的數(shù)據(jù)超過一半,釋放一些內(nèi)存Person & RemoveElement();
//從Set中的index索引處移除成員
//如果Set空的數(shù)據(jù)超過一半,釋放一些內(nèi)存
? ? ? ?Person & RemoveElement( int index );
? ? ? ?int Size(); //answer the number of elements in the set.void ? ? ? ? ? ? ? ? ?
? ? ? ?Print();//print the elements of the set
? ? ? //void Reset();
private:
? ? ? ?Person ** _elements;
? ? ? int? _capacity ; ?//volume of the set
? ? ? int? _size ; ? ? ?//number of elements in the set
? ? ? int _index ;
} ;
Growable Sets(可擴展的Set)
你的Set應(yīng)該使用一個數(shù)組來存儲成員并且數(shù)組應(yīng)該使用new在堆上分配.
當set被創(chuàng)建時,它有一個指定的尺寸(指數(shù)組).如果它滿了,必須從堆中開辟更多的內(nèi)存.這個將會在某一次Add()函數(shù)的期間.
如果set中有太多空的位置了(數(shù)組),它應(yīng)該去釋放它的一些內(nèi)存.這將發(fā)生在某一次remove函數(shù)調(diào)用的期間.
建議:?如果有一半以上空間未存儲Person指針(也就是上面所說的空),那么它就去釋放一些內(nèi)存(一半內(nèi)存).
你的set類應(yīng)該在它擴展和縮小空間是用cout打印出一串信息.這個信息應(yīng)該標明內(nèi)存開辟或釋放后的所能存儲的最大值(capacity).
這里是容器的用于基本的擴展和縮小空間的實現(xiàn).
你可以用這些代碼來作為你實現(xiàn)的基本代碼.
void AddElement( Person& aPerson )
{
// Relocate the array space
? ? ? ?if ( size == capacity )
? ? ? ?{
? ? ? ?Person** temp = _elements;
? ? ? ?_elements = new Person*[capacity*2];
? ? ? ?for( int i=0; i<size;i++)
? ? ? ? ? {
? ? ? ? ? ? ? ? ?_elements [i] = temp[i];
? ? ? ? ? }
? ? ? ?capacity*= 2;
? ? ? ?delete [] temp;
? ? ? ?}
? ? ? ?_elements[size++] = &aPerson;
}
Person& RemoveElement()
{
? ? ? ?size--;
? ? ? ?Person* p = _elements[size];//shrink the container
? ? ? ?if(size < capacity/2)
? ? ? ?{
? ? ? ? ? ? ?cout << "shrinking\n";
? ? ? ? ? ? ?Person** temp = _elements;_elements = new Person*[capacity/2];
? ? ? ? ? ? ?for ( int i=0; i<size;i++)
? ? ? ? ? ? ?{
? ? ? ? ? ? ? ? ? ? ? _elements [i] = temp[i];
? ? ? ? ? ? ? }
? ? ? ? ? ? ? capacity /= 2;
? ? ? ? ? ? ? delete [] temp;
? ? ? ?}
? ? ? ?return *p;
}
迭代:
NextElement()函數(shù)為簡單的迭代器??供了一個方法.
NextElement()函數(shù)應(yīng)該在set每次調(diào)用時都返回下一個成員.
特別的,如果NextElement()函數(shù)在一個尺寸為n的set中被調(diào)用了n次,
那么它應(yīng)該也就迭代通過了set的所有成員(訪問了所有成員)..
如果你有一個n尺寸的set,如果在第n次之后(n+1)再調(diào)用NextElement()函數(shù),將會從開頭再次迭代.要實現(xiàn)這個或許要添加一個私有成員變量,在set中是index,來保持當前元素和每次NextElement()調(diào)用時的位置(track) ,它可以讓index每次增加并且在適當?shù)臅r候返回第0個索引位置.
(也就是說NextElement靠私有成員_index來控制位置的.)...
第三部分)添加const修飾
應(yīng)該在參數(shù)的地方添加const修飾符,或函數(shù)應(yīng)該是const保護.
對你完成程序的第一部分和第二部分進行如下改變.
R3.1)這個將要求你像Print()函數(shù)那樣作為const來定義.
例如:
void Print() const { ... }
R3.2) .
改變一下SetOfPersons類里的public接口,以便可以讓它們需要的時候
使用const修飾符.
//file SetOfPersons.hclass PersonSet
{
public:
? ? ? ?PersonSet (int initial_size = 4) ;
? ? ? ?~ PersonSet (void) ;
? ? ? ?void Add(Person & element) ;
? ? ? ?Person & NextElement()const ;
? ? ? ?Person & RemoveElement() ;
? ? ? ?Person & RemoveElement( int index ) ;
? ? ? ?int Size() const?;
? ? ? ?void Print() const?;
private:
? ? ? ? Person ** _elements;
? ? ? ? int? ? _capacity;? //volume of the set
? ? ? ? int? ? _size; ? ? ? //number of elements in the set
? ? ? ? int ? ?_index;
} ;
R3.3)在任何地方的const及const類里放置const的標識符,都應(yīng)該有const修飾符.
2.測試要求第四部分)測試規(guī)格
R4.1)在完成了你的類之后,你應(yīng)該可以在執(zhí)行下面的主程序
//file main.cpp
#include <iostream>
#include<string.h>
#include "Date.h"
#include "Person.h"
#include " PersonSet.h"
using namespace std;
int main()
{
//declare some const persons
? ? ? ?Person *p1 = new Person("Lou", "lou@chat.ca", 20, 6, 1960);
? ? ? ?Person *p2 = new Person("Frank", "f123@chat.ca", 20, 3, 1967);
? ? ? ?Person *p3 = new Person("Ann", "ann@chat.ca", 20, 8, 1960);
? ? ? ?PersonSet boys, girls;
? ? ? ?boys.Add( *p1);
//test to see if the same object is retrieved from the set.
? ? ? ?if (p1 != &boys.RemoveElement( ) )
? ? ? ?{
? ? ? ? ? ?cout << "ERROR: the objects are different \n";
? ? ? ?}
? ? ? ?else
? ? ? ?{
? ? ? ? ? cout << "Good, the objects are the same \n";
? ? ? ?}
? ? ? ?boys.Add( *p1);
? ? ? ?boys.Add( *p2);
? ? ? ?girls.Add( *p3);
? ? ? ?boys.Add(*(new Person("John", "f123@chat.ca", 20, 3, 1967)));
? ? ? ?girls.Add(*(new Person("Sue", "f123@chat.ca", 20, 3, 1967)));
? ? ? ?boys.Add(*(new Person("Frank", "frank@chat.ca", 25, 4, 1958)));
? ? ? ?girls.Addd(*(new Person("Mary", "mary@chat.ca", 25, 4, 1955)));
? ? ? ?boys.Add(*(new Person("John", "johnchat.ca", 12, 12, 1970)));
?//print all the boys using the removeSomeElement() method and delete them
? ? ? ?int numberOfBoys = boys.Size();
? ? ? ?cout << "number of boys = " << numberOfBoys << "\n";
? ? ? ?for(int i = 0; i<numberOfBoys;i++)
? ? ? {?
? ? ? ? ? ? Person & boy = boys.RemoveElement();
? ? ? ? ? ? boy.Print();?
? ? ? ? ? ? delete &boy;
? ? ? ?}
//print the girls using the << operator of the SetOfPersons class
? ? ? ?cout << "number of girls = " << girls.size() << "\n";
? ? ? ?girls.Print();
//print of the girls birthdays and using the someElement() method
? ? ? ?int numberOfGirls = girls.Size();
? ? ? ?girls.Reset();
? ? ? ?for(int i = 0; i<numberOfGirls;i++)
? ? ? {
? ? ? ? ? ? ?girl.NextElement().GetBirthDate() .Print();
? ? ? ?}?
//delete all the girls from the heap
? ? ? ?int numberOfGirls = girls.Size();
? ? ? for(int i = 0; i<numberOfGirls;i++)
? ? ? {
? ? ? ? ? ? Person & her = girls.RemoveElement();
? ? ? ? ? ? delete &her;
? ? ? }
}?
//end of main;
最后代碼的結(jié)果要求為:
R4.2)?修改主程序以便它可以正確無誤的演示擴展和縮小.
R4.3)?你應(yīng)該??供或修改主程序來測試所有要求 并且打印出執(zhí)行結(jié)果.
R4.4) 你的代碼不應(yīng)該有任何的內(nèi)存泄露或多次釋放.
R4.5) 所有的堆對象應(yīng)該在main函數(shù)返回之前釋放.
R4.5) 你能在添加一個新元素到數(shù)組中之前來檢查界限.