I understand inheritence, that part is easy, but like, how do classes use each other? How do they work together? theyre seperate objects....
Here are some examples:
(Note: don't let vectors or other STL containers and their notation scare you. A vector is similar to an array except it doesn't have a fixed size, so you can add as many elements to it as you want. Typically, you add another element using push_back(), which adds the element to the end of the vector. In addition, the notation tells you what's in the vector, e.g.:
vector<int> myInts;
The vector, which remember is like an array, can contain integers. Here's another one:
vector<Card> myCards;
The vector can contain Card objects. Finally,
vector<Card*> deck;
The vector can store pointers to Card objects.)
A Deck of Card's that can be shuffled, displayed, and dealt.
Code:
#include <iostream>
#include <ctime> //time()
#include <vector>
#include <algorithm> //random_shuffle()
using namespace std;
class Card
{
public:
Card(int rank_, int suit_)
{
rank = rank_;
suit = suit_;
}
Card()
{
rank = suit = 0;
}
//To be able to cout<< Card(s):
friend ostream& operator<<(ostream& out, const Card* aCard);
friend ostream& operator<<(ostream& out, const vector<Card*>& aHand);
private:
int rank;
int suit;
};
//To cout<< one Card:
ostream& operator<<(ostream& out, const Card* aCard)
{
switch (aCard->rank)
{
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
cout<<aCard->rank;
break;
case 1:
cout<<"Ace";
break;
case 11:
cout<<"Jack";
break;
case 12:
cout<<"Queen";
break;
case 13:
cout<<"King";
break;
default:
cout<<"error";
}
switch(aCard->suit)
{
case 1:
cout<<" of Clubs";
break;
case 2:
cout<<" of Diamonds";
break;
case 3:
cout<<" of Hearts";
break;
case 4:
cout<<" of Spades";
break;
default:
cout<<"error";
}
return out;
}
//A function that enables you to cout<< a vector of
//Card's(either a hand or a deck). It's the same function as for
//displaying a single card, but with a for loop to go through the
//whole vector:
ostream& operator<<(ostream& out, const vector<Card*>& aHand)
{
for(int i = 0; i < aHand.size(); i++)
{
switch (aHand[i]->rank)
{
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
case 8:
case 9:
case 10:
cout<<aHand[i]->rank;
break;
case 1:
cout<<"Ace";
break;
case 11:
cout<<"Jack";
break;
case 12:
cout<<"Queen";
break;
case 13:
cout<<"King";
break;
default:
cout<<"error";
}
switch(aHand[i]->suit)
{
case 1:
cout<<" of Clubs";
break;
case 2:
cout<<" of Diamonds";
break;
case 3:
cout<<" of Hearts";
break;
case 4:
cout<<" of Spades";
break;
default:
cout<<"error";
}
cout<<endl;
//Prevents scrolling off the screen:
if( (i != 0) && (i%20 == 0))
{
cout<<"Continue? <Hit Return>";
cin.get();
cout<<endl;
}
}
return out;
}
class Deck
{
public:
Deck()
{
for(int i=1; i <= 13; i++)
{
for(int j=1; j <= 4; j++)
{
//Add a card to the end of the deck member variable:
deck.push_back(new Card(i, j));
}
}
delt = 0;
}
~Deck()
{
//Delete the memory allocated with new:
for(vector<Card*>::iterator i = deck.begin(); i != deck.end(); i++)
{
delete *i;
}
}
void showDeck()
{
cout<<deck<<endl;
}
void shuffle()
{
//Seed random number generator with current time:
srand(time(0));
//Shuffle deck:
random_shuffle(deck.begin(), deck.end());
//After shuffling, set the number of cards dealt back to 0:
delt = 0;
}
void deal(const int numCards, vector<Card*>& theHand)
{
for(int i=0; i<numCards; i++)
{
if(delt < 52)
{
//No cards are actually delt from the deck: pointers to Card's
//in the deck are put in the Hand instead, and the Cards all stay in the
//deck. The member variable 'delt' is advanced from the top of the
//deck down into the deck as the cards are delt, and it marks where
//the next card is.
theHand.push_back(deck[delt]);
++delt;
}
else
theHand[i] = 0;
}
}
//A function to cout<< the 'deck' member variable
//(uses same friend function as Card):
friend ostream& operator<<(ostream& out, const vector<Card*>& deck);
private:
//A vector of Card pointers is similar to an array of Card pointers:
vector<Card*> deck;
int delt;
};
int main()
{
Deck myDeck;
myDeck.showDeck();
myDeck.shuffle();
vector<Card*> player1;
vector<Card*> player2;
myDeck.deal(5,player1);
myDeck.deal(5,player2);
cout<<player1<<endl<<endl
<<player2<<endl;
return 0;
}
Ducks and Inheritance:
Code:
#include<iostream>
using namespace std;
class Duck
{
public:
virtual void species() = 0;
};
////////////////////////////
class Sound
{
public:
virtual void speak() = 0;
};
class Quack: public Sound
{
private:
void speak()
{
cout<<"Quack, quack."<<endl;
}
};
class Squeak: public Sound
{
private:
void speak()
{
cout<<"Squeak, squeak."<<endl;
}
};
//////////////////////////////
class Mallard : public Duck
{
public:
Mallard()
{
Q = new Quack;
}
~Mallard()
{
delete Q;
}
void species()
{
cout<<"Mallard"<<endl;
}
Quack* getSound()
{
return Q;
}
private:
Quack* Q;
};
class RubberDuck : public Duck
{
public:
RubberDuck()
{
S = new Squeak;
}
~RubberDuck()
{
delete S;
}
void species()
{
cout<<"Rubber"<<endl;
}
Squeak* getSound()
{
return S;
}
private:
Squeak* S;
};
//Because the following function has parameters that are base
//class pointers it can handle any Duck that makes any Sound.
void operateDuck(Duck* const pDuck, Sound* const pSound)
{
pDuck->species();
pSound->speak();
}
int main()
{
Mallard myDuck;
RubberDuck yourDuck;
operateDuck(&myDuck, myDuck.getSound());
cout<<endl;
operateDuck(&yourDuck, yourDuck.getSound());
return 0;
}
That is what I vaguely remember of the first design problem in the book "Head First Design Patterns":
http://www.amazon.com/exec/obidos/tg...books&n=507846
It seemed like a really interesting and easy to read book, although it's written for Java. If you note that an "interface" in Java is the same thing as a pure abstract class in C++(i.e. a class with all virtual functions and no definitions for the funtions), then you should be able to understand at least the first chapter if you want to take a look at it in the bookstore some time.