
Arrays and Classes in Object-Oriented Programming with C++
Explore the concepts of arrays and classes in C++, including declaring arrays of objects, initializing objects using constructors, indexing arrays, and using arrays as class member data. Learn how arrays differ from lists and how to create safer array types within classes.
Download Presentation

Please find below an Image/Link to download the presentation.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.
You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.
The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.
E N D
Presentation Transcript
Arrays and Classes Andy Wang Object Oriented Programming in C++ COP 3330
Arrays of Objects Declaring Array is an indexed collection of data elements of the same type Index is between 0 and size 1 We can have array of objects Fraction rationals[20]; // array of 20 Fraction objects Complex nums[50]; Hydrant fireplugs[10]; // an array of 10 objects of type Hydrant In an array of objects, each array position is a single object rationals has 20 objects named rationals[0], rationals[1] rationals[19] // an array of 50 Complex objects
Initialization Normally, the constructor initializes an object The default constructor (if available) is invoked for each object in an array Fraction numList[4]; // builds 4 fractions using default constructor
Initialization With different constructors, which constructor is invoked for each object in an array? Use initializer set Fraction numList[3] = { Fraction(2,4), Fraction(5), Fraction() }; // allocates an array of 3 fractions, initialized to 2/4, 5/1, and 0/1.
Using Arrays of Objects Indexing the same as with regular arrays Dot-operator works the same as with single names objectName.memberName Name of each object is arrayName[index] Examples Fraction rationals[20]; rationals[2].Show(); rationals[6].Input(); cout << rationals[18].Evaluate(); // create an array of 20 Fraction objects // displays the third Fraction object // calls Input function for the 7thFraction
Arrays as Class Member Data C-style arrays are pretty primitive No boundary checks; unsafe Array can be used as a member data of a class Member functions can error check boundary conditions A good way to create safer array types
Example: DList http://www.cs.fsu.edu/~myers/cop3330/examples/arrays/ dlist/ List of up to 10 values of type double, not always full Member data current tracks the number of elements in the list The list is not the same as the array The array is the physical storage used by the class The list is an abstract concept that an object of this class type represents
Example: DList Note since the array is member data of a class No need to pass the array as a parameter
dlist.h constint MAX = 10; class DList { public: DList(); bool Insert(double item); // inserts item (if room) double GetElement(unsigned int index) const; void Print() const; intGetSize() const; private: double array[MAX]; int current; // number of stored items }; // prints the list // number of stored items
dlist.cpp #include <iostream> #include DList.h using namespace std; DList::DList() { current = 0; } bool DList::Insert(double item) { if (current >= MAX) return false; array[current] = item; current++; return true; }
dlist.cpp double DList::GetElement(unsigned int n) const{ if (n >= current) n = current 1; // broken if n == 0 return array[n]; } void DList::Print() const{ if (current == 0) { cout<< Empty List ; return; } int i; for (i = 0; i < current 1; i++) // print all but the last cout<< array[i] << , ; cout<< array[i]; // print the last } int DList::GetSize() const{ return current; }
main.cpp #include <iostream> #include dlist.h using namespace std; int main() { DList d; cout<< Initial list:\n ; d.Print(); d.Insert(5.4); d.Insert(2.3); d.Insert(10.67); d.Print(); }
Exercises Try to add the following member functions to the class bool Delete(unsigned int index); // delete the specified, // returntrue for success, false otherwise double Sum(); // return the sum of the list elements double Average(); // return the average of elements double Max(); // return the max value in the list void Clear(); // reset the list to empty intGreater(double x); // return the number of list // elements that are greater than x
Example: Blackjack Card Game Simulation http://www.cs.fsu.edu/~myers/cop3330/examples/bjack/ Multiple classes, using composition relationship Card objects embedded in the Deck (components) Deck and Player objects are member data of class Dealer (manager class) Arrays of objects as member data Use member data to track array usage Enumeration usage (suits of the cards)
carddeck.h enumSuit {CLUBS, DIAMONDS, HEARTS, SPADES}; class Card { public: void Display() const; void SetSuit(Suit); void SetVal(int); Suit GetSuite() const; intGetVal() const; private: Suit s; int val; // 2 14, representing 2..10, J, Q, K, A };
carddeck.h class Deck { public: Deck(); void Shuffle(); void ShuffleRest(); // shuffle the undealt cards Card DealCard(); // deal one card from the deck intTopCard() const; private: int topCard; // index of current top card of deck // tracking the current state of the deck Card cards[52]; // notice the composition };
carddeck.cpp #include <iostream> // for cout #include <cstdlib> #include <ctime> #include carddeck.h // for rand(), srand() // for clock() using namespace std;
carddeck.cpp void Card::Display() const{ if ((2 <= val) && (val <= 10)) cout<< val; else { switch(val) { case 11: cout<< J ; break; case 12: cout<< Q ; break; case 13: cout<< K ; break; case 14: cout<< A ; break; } }
carddeck.cpp switch(s) { case CLUBS: cout<< of clubs ; break; case DIAMONDS: cout<< of diamonds ; break; case HEARTS: cout<< of hearts ; break; case SPADES: cout<< of spades ; break; } cout<< \n ; }
carddeck.cpp void Card::SetSuit(Suit suit) { s = suit; } Void Card::SetVal(int v) { val = v; } Suit Card::GetSuit() const{ return s; } intCard::GetVal() const{return val; } void Randomize() { unsigned int seed = unsigned(clock()); srand(seed); }
carddeck.cpp Deck::Deck() { topcard= 0; for (int i= 0; i< 52; i++) { cards[i].SetVal((i % 13) + 2); // val = 2..14 switch(i/13) { case 0: cards[i].SetSuit(CLUBS); case 1: cards[i].SetSuit(DIAMONDS); case 2: cards[i].SetSuite(HEARTS); case 3: cards[i].SetSuit(SPADES); } } }
carddeck.cpp Deck::Shuffle() { Randomize(); for (int i= 0; i< 3; i++) { // shuffle 3 times for (int j = 0; j < 52; j++) { int r = rand() % 52; Card c = cards[j]; cards[j] = cards[r]; cards[r] = c; } } topCard= 0; // no cards dealt yet }
carddeck.cpp Deck::ShuffleRest() { Randomize(); for (int i= 0; i< 3; i++) { // shuffle 3 times for (int j = topCard; j < 52; j++) { int r = rand() % (52 topCard) + topCard; Card c = cards[j]; cards[j] = cards[r]; cards[r] = c; } } }
carddeck.cpp // yet to error check the exhausted deck Card Deck::DealCard() { Card deal; deal = cards[topCard]; topCard++; return deal; } int Deck::TopCard() const{ return topCard; }
player.h #include carddeck.h class Player { public: Player(); void ClearHand(); void TakeCard(Card c); int NumCards() const; intGetPot() const; void AddToPot(int val); int HandValue() const; // compute the hand value void ShowHand() const; private: Card hand[5]; int pot; int numCards; }; Variable tracks the number of allocated array slots in use
player.cpp #include <iostream> #include player.h using namespace std; Player::Player() { pot = 10; ClearHand(); } void Player()::ClearHand() { numCards = 0; } void Player::TakeCard(Card c) { if (numCards == 5) return; hand[numCards] = c; numCards++; } int Player::NumCards() const { return numCards; }
player.cpp int Player::GetPot() const { return pot; } void Player::AddToPot(int val) { pot += val; } int Player::HandValue() const { int v, total = 0; for (int i = 0; i < numCards; i++) { v = hand[i].GetVal(); if (v <= 10) total += v; else if (v <= 13) total += 10; else total += 11; } return total; } // for simplicity
player.cpp void Player::ShowHand() const { cout << \nPLAYER #1 s hand: \n ; for (int i = 0; i < numCards; i++) hand[i].Display(); cout << *** Total value: << HandValue() << \n ; } Example use of the tracking variable
utility.h int ReadyToQuit(); // return 1 if user enters y or Y // freeze the screen until the user types a character void WaitForUser();
utility.cpp int ReadyToQuit() { char ans; cout << \nDo you wish to run the program again (Y for yes, N for no)? ; cin >> ans; ans = toupper(ans); while ((ans != Y ) && (ans != N )) { cout << \nPlease answer again with Y or N ; cout << \n\tRun the program again? ; cin >> ans; ans = toupper(ans); } return (ans == N ); // returns 1 when ready to quit }
utility.cpp void WaitForUser() { cout << \nPress c followed by Enter to continue ; char any; cin >> any; cout << \n ; }
dealer.h #include player.h class Dealer { public: Dealer(); void PlayGame(); void DetermineResults(); private: Player p; // only support one player for now Deck d; Card hand[5]; int numCards;
dealer.h int HandValue(int) const; // compute the hand value // starting with specified card void ShowHand(int) const; // display hand starting // with specified card void Shuflfe(); void DealHand(); // other helper functions void StartHand(); // deal the first 2 cards to each player void DealACardToPlayer(); void DealACardToDealer(); void DealPlayerCards(); void DealDealerCards(); void FindBestHand(); int EndofDeck() const;
dealer.cpp #include <iostream> #include <cctype> // for toupper using namespace std; Dealer::Dealer() { d.Shuffle(); numCards = 0; } void Dealer::PlayGame() { cout << \n\nGame on!!!\n\n ; do { DealHand(); FindBestHand(); } while (!EndOfDeck()); }
dealer.cpp void Dealer::DetermineResults() { cout << \n\nPLAYER #1 started with a pot of 10\n ; cout << *** FINAL POT: << p.GetPot() << \n ; } void Dealer::ShowHand(int startCard) const { cout << \nDealer s hand: \n ; for (int i = startCard; I < numCards; i++) hand[i].Display(); cout << *** value showing: << HandValue(startCard) << \n ; }
dealer.cpp int Dealer::HandValue(int startCard) const { int v, total = 0; for (int i = startCard; i < numCards; i++) { v = hand[i].GetVal(); if (v <= 10) total += v; else if (v <= 13) total += 10; else total += 11; } return total; }
dealer.cpp int Dealer::DealHand() { StartHand(); DealPlayerCards(); DealDealerCards(); } void Dealer::StartHand() { p.ClearHand(); numCards = 0; for (int i = 0; i < 2; i++) { DealACardToPlayer(); DealACardToDealer(); } p.ShowHand(); ShowHand(1); }
dealer.cpp void Dealer::DealACardToPlayer() { p.TakeCard(d.DealCard()); } void Dealer::DealACardToDealer() { hand[numCards++] = d.DealCard(); }
dealer.cpp void Dealer::DealPlayerCards() { char ans; do { cout << \nDo you want another card ; cout << (Y for yes, N for no)? ; cin >> ans; ans = toupper(ans); if (ans == Y ) { DealACardToPlayer(); p.ShowHand(); } } while ((ans == Y ) && (p.HandValue() < 21) && (p.NumCards() <= 5)); }
dealer.cpp void Dealer::DealDealerCards() { ShowHand(0); while ((HandValue(0) < 17) && (numCards <= 5)) { DealACardToDeader(); ShowHand(0); } }
dealer.cpp void Dealder::FindBestHand() { int pVal = p.HandValue(), dVal = HandValue(0); if (((pVal <= 21) && (pVal > dVal)) || (dVal > 21)) { cout << Player #1 wins hand\n ; p.AddToPot(1); } else if (((dVal <= 21) && (dVal > pVal)) || (pVal > 21)) { cout << Computer wins hand\n ; p.AddToPot(-1); } else { cout << Hand was a draw\n ; } WaitForUser(); }
dealer.cpp // we need (at most) 10 cards int Dealer::EndOfDeck() const { return (d.TopCard() >= 42); }
game.cpp #include <iostream> #include dealer.h #include utility.h using namespace std; int main() { do { Dealer theDealer; theDealer.PlayGame(); theDealer.DetermineResults(); } while (!ReadyToQuit()); cout << Goodbye!\n ; return 0; }