Cannot instantiate abstract class error

Nov 29, 2011 at 1:34am
Hello, I have been racking my brain trying to resolve these error messages in Visual Studio, but apparently I'm lacking some fundamental knowledge related to this issue. Any help, suggestion, or comment would be greatly appreciated. I thank you in advance.

The following are the 6 error message I'm getting MSVC 2010.

Error 1	error C2259: 'GenericPlayer': cannot instantiate abstract class playerImp.cpp

Error 2	error C2259: 'GenericPlayer': cannot instantiate abstract class playerImp.cpp

Error 3	error C2259: 'GenericPlayer': cannot instantiate abstract class playerImp.cpp

Error 4	error C2259: 'GenericPlayer': cannot instantiate abstract class playerImp.cpp

Error 5	error C2259: 'GenericPlayer': cannot instantiate abstract class genericPlayerImp.cpp

Error 6	error C2259: 'GenericPlayer': cannot instantiate abstract class genericPlayerImp.cpp


Below are the 3 classes related to these errors. I also clearly marked the lines where the errors point to (the errors are in bold and numbered in the code):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
/////////////////////////
//genericPlayerImp.cpp //
/////////////////////////

#include "genericPlayer.h"

#include <iostream>

using namespace std;

ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer)
{
    os << aGenericPlayer.m_Name << ":\t"; //ERROR 5
    
    vector<Card*>::const_iterator pCard;
    if (!aGenericPlayer.m_Cards.empty())
    {
        for (pCard = aGenericPlayer.m_Cards.begin(); 
             pCard != aGenericPlayer.m_Cards.end(); ++pCard)
            os << *(*pCard) << "\t";

        if (aGenericPlayer.GetTotal() != 0)
            cout << "(" << aGenericPlayer.GetTotal() << ")";
    }
    else
    {
        os << "<empty>";
    }
        
    return os;
}

GenericPlayer::GenericPlayer(const string& name): m_Name(name)
{}

GenericPlayer::~GenericPlayer()  
{}

bool GenericPlayer::IsBusted() const
{ 
    return (GetTotal() > 21);
}

void GenericPlayer::Bust() const
{
    cout << m_Name << " busts.\n";  //ERROR 6
}

//-----------------------------------------------------------------------

////////////////////
//genericPlayer.h //
////////////////////

#ifndef GENERICPLAYER_H
#define GENERICPLAYER_H

#include "hand.h"

class GenericPlayer : public Hand
{
    friend ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer);

public:
    GenericPlayer(const string& name = "");
    
    virtual ~GenericPlayer();

    virtual bool IsHitting() const = 0;

    bool IsBusted() const;

    void Bust() const;

protected:
    string m_Name;
};

#endif

//--------------------------------------------------------------

///////////////////
// playerImp.cpp //
///////////////////

#include "player.h"
#include "genericPlayer.h"
using namespace std;

Player::Player(const string& name): GenericPlayer(name)
{}

Player::~Player()
{}
    
bool Player::IsHitting() const
{
    cout << m_Name << ", do you want a hit? (Y/N): "; //ERROR 1
    char response;
    cin >> response;
    return (response == 'y' || response == 'Y');
}

void Player::Win() const
{
    cout << m_Name <<  " wins.\n"; //ERROR 2
}

void Player::Lose() const
{
    cout << m_Name <<  " loses.\n"; //ERROR 3
}

void Player::Push() const
{
    cout << m_Name <<  " pushes.\n"; //ERROR 4 
}
 
Nov 29, 2011 at 3:12am
69
70
    virtual bool IsHitting() const = 0;
        //this is a pure virtual function! 
By having a pure virtual function, you make your class abstract, meaning that you have to make another class inherit from it and define that function. You cannot instantiate abstract classes, it's just the way it works.
Nov 29, 2011 at 1:33pm
Thank you, LB, didn't know this fact. What would be the best solution in this case?
Nov 29, 2011 at 1:39pm
That depends on you - did you want to make it abstract or did you just want that function to do nothing? If that function should not be available at this level of inheritance but you want to instantiate the class, just don't define or declare it.
Dec 3, 2011 at 3:55pm
Dear LB. I have tried to imply your suggestions. I spent at least another 20 hours on this using your advise, but I still cannot get it to work. The interesting thing is that I can get it to work when I put all the classes in one file. At this point, I'm attaching the whole code in 2 different messages (starting with the header files and main). Please if you could be so kind as to run the code and let me know what the solution is. Thanking you in advance:

//card.h
#ifndef CARD_H
#define CARD_H

#include <iostream>

using namespace std;

class Card
{
//overloading << operator so can send Card object to standard output
friend ostream& operator << (ostream& os, const Card& aCard);

public:
enum rank {ACE = 1, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN,
JACK, QUEEN, KING};
enum suit {CLUBS, DIAMONDS, HEARTS, SPADES};

Card(rank r = ACE, suit s = SPADES, bool ifu = true);

//returns the value of a card, 1 - 11
int GetValue() const;

//flips a card; if face up, becomes face down and vice versa
void Flip();

private:
rank m_Rank;
suit m_Suit;
bool m_IsFaceUp;
};

#endif

---------------------------------------------------------------------------------------

//deck.h
#ifndef DECK_H
#define DECK_H

#include "hand.h"
#include "genericPlayer.h"

class Deck : public Hand
{
public:
Deck();

virtual ~Deck();

//create a standard deck of 52 cards
void Populate();

//shuffle cards
void Shuffle();

//deal one card to a hand
void Deal(Hand& aHand);

//give additional cards to a generic player
void AdditionalCards(GenericPlayer& aGenericPlayer);
};

#endif

---------------------------------------------------------------------------------------

//game.h
#ifndef GAME_H
#define GAME_H

#include "deck.h"
#include "house.h"
#include "player.h"
#include <algorithm>
#include <ctime>

class Game
{
public:
Game(const vector<string>& names);

~Game();

//plays the game of blackjack
void Play();

private:
Deck m_Deck;
House m_House;
vector<Player> m_Players;
};

#endif

---------------------------------------------------------------------------------------

//genericPlayer.h
#ifndef GENERICPLAYER_H
#define GENERICPLAYER_H

#include "hand.h"

class GenericPlayer : public Hand
{
friend ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer);

public:
GenericPlayer(const string& name = "");

virtual ~GenericPlayer();

//indicates whether or not generic player wants to keep hitting
virtual bool IsHitting() const = 0;

//returns whether generic player has busted - has a total greater than 21
bool IsBusted() const;

//announces that the generic player busts
void Bust() const;

protected:
string m_Name;
};

#endif

---------------------------------------------------------------------------------------

//hand.h
#ifndef HAND_H
#define HAND_H

#include "card.h"
#include <vector>

class Hand
{
public:
Hand();

virtual ~Hand();

//adds a card to the hand
void Add(Card* pCard);

//clears hand of all cards
void Clear();

//gets hand total value, intelligently treats aces as 1 or 11
int GetTotal() const;

protected:
vector<Card*> m_Cards;
};

#endif

---------------------------------------------------------------------------------------

//house.h
#ifndef HOUSE_H
#define HOUSE_H

#include "genericPlayer.h"

class House : public GenericPlayer
{
public:
House(const string& name = "House");

virtual ~House();

//indicates whether house is hitting - will always hit on 16 or less
virtual bool IsHitting() const;

//flips over first card
void FlipFirstCard();
};


#endif

---------------------------------------------------------------------------------------

//player.h
#ifndef PLAYER_H
#define PLAYER_H

#include "genericPlayer.h"

class Player : public GenericPlayer
{
public:
Player(const string& name = "");

virtual ~Player();

//returns whether or not the player wants another hit
virtual bool IsHitting() const;

//announces that the player wins
void Win() const;

//announces that the player loses
void Lose() const;

//announces that the player pushes
void Push() const;
};

#endif

---------------------------------------------------------------------------------------

//blackJack.cpp
#include <iostream>
#include <vector>
#include "game.h"
#include "card.h"
#include <algorithm>
#include <ctime>
#include <string>

using namespace std;

int main()
{
cout << "\t\tWelcome to Blackjack!\n\n";

int numPlayers = 0;
while (numPlayers < 1 || numPlayers > 7)
{
cout << "How many players? (1 - 7): ";
cin >> numPlayers;
}

vector<string> names;
string name;
for (int i = 0; i < numPlayers; ++i)
{
cout << "Enter player name: ";
cin >> name;
names.push_back(name);
}
cout << endl;

//the game loop
Game aGame(names);
char again = 'y';
while (again != 'n' && again != 'N')
{
aGame.Play();
cout << "\nDo you want to play again? (Y/N): ";
cin >> again;
}

return 0;
}
Dec 3, 2011 at 3:59pm
1
2
//indicates whether or not generic player wants to keep hitting
virtual bool IsHitting() const = 0;

As I have said before, this makes the class abstract and you can never make an instance of it.

Either define the function and remove the = 0, or create a class that inherits from GenericPlayer and that defines this function.


I misread the code.
Last edited on Dec 3, 2011 at 4:17pm
Dec 3, 2011 at 4:13pm
[code] "Please keep using code tags" [/code]
Well, 'Player' derives from 'Generic Player' and it does implement that function.
¿Where are you trying to instantiate a Generic Player?

Also
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef GENERICPLAYER_H
#define GENERICPLAYER_H

#include "hand.h"
#include <string>
#include <iostream> //I guess that you could forward declare too. 


class GenericPlayer : public Hand
{
    friend std::ostream& operator<<(std::ostream& os, const GenericPlayer& aGenericPlayer);
/* */
protected:
    std::string m_Name; // you need to put the namespace qualifier
};

#endif 
Dec 3, 2011 at 4:28pm
Remaining implementation code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
//cardImp.cpp
#include "card.h"
#include <string>
#include <iostream>
using namespace std;

//overloads << operator so Card object can be sent to cout
ostream& operator << (ostream& os, const Card& aCard)
{
    const string RANKS[] = {"0", "A", "2", "3", "4", "5", "6", "7", "8", "9", 
                            "10", "J", "Q", "K"};
    const string SUITS[] = {"c", "d", "h", "s"};

    if (aCard.m_IsFaceUp)
        os << RANKS[aCard.m_Rank] << SUITS[aCard.m_Suit];
    else
        os << "XX";

    return os;
}

Card::Card(rank r, suit s, bool ifu):  m_Rank(r), m_Suit(s), m_IsFaceUp(ifu)
{} 

int Card::GetValue() const
{
    //if a cards is face down, its value is 0
    int value = 0;
    if (m_IsFaceUp)
    {
        //value is number showing on card
        value = m_Rank;
        //value is 10 for face cards
        if (value > 10)
            value = 10;
    }
    return value;
}

void Card::Flip()
{
    m_IsFaceUp = !(m_IsFaceUp);
}

/////
//deckImp.cpp
/////
#include "deck.h"
#include <algorithm>
#include <ctime>

Deck::Deck()
{ 
    m_Cards.reserve(52);
    Populate();
}

Deck::~Deck()
{}

void Deck::Populate()
{
    Clear();
    //create standard deck
    for (int s = Card::CLUBS; s <= Card::SPADES; ++s)
            for (int r = Card::ACE; r <= Card::KING; ++r)
                Add(new Card(static_cast<Card::rank>(r), static_cast<Card::suit>(s)));
}

void Deck::Shuffle()
{
    random_shuffle(m_Cards.begin(), m_Cards.end());
}

void Deck::Deal(Hand& aHand)
{
    if (!m_Cards.empty())
    {
        aHand.Add(m_Cards.back());
        m_Cards.pop_back();
    }
    else
    {
        cout << "Out of cards. Unable to deal.";
    }
}

void Deck::AdditionalCards(GenericPlayer& aGenericPlayer)
{
    cout << endl;
    //continue to deal a card as long as generic player isn't busted and
    //wants another hit
    while ( !(aGenericPlayer.IsBusted()) && aGenericPlayer.IsHitting() )
    {
        Deal(aGenericPlayer);
        cout << aGenericPlayer << endl;
        
        if (aGenericPlayer.IsBusted())
            aGenericPlayer.Bust();
    }
}

/////
//gameImp.cpp
////
#include "game.h"

Game::Game(const vector<string>& names)
{
    //create a vector of players from a vector of names       
    vector<string>::const_iterator pName;
    for (pName = names.begin(); pName != names.end(); ++pName)      
        m_Players.push_back(Player(*pName));

    srand(time(0));    //seed the random number generator
    m_Deck.Populate();
    m_Deck.Shuffle();
}

Game::~Game()
{}

void Game::Play()
{         
    //deal initial 2 cards to everyone
    vector<Player>::iterator pPlayer;
    for (int i = 0; i < 2; ++i)
    {
        for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)      
            m_Deck.Deal(*pPlayer);
        m_Deck.Deal(m_House);
    }
    
    //hide house's first card
    m_House.FlipFirstCard();    
    
    //display everyone's hand
    for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)      
        cout << *pPlayer << endl;
    cout << m_House << endl;

    //deal additional cards to players
    for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)
        m_Deck.AdditionalCards(*pPlayer);    

    //reveal house's first card
    m_House.FlipFirstCard();    
    cout << endl << m_House; 
  
    //deal additional cards to house
    m_Deck.AdditionalCards(m_House);

    if (m_House.IsBusted())
    {
        //everyone still playing wins
        for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)      
            if ( !(pPlayer->IsBusted()) )
                pPlayer->Win();
    }
    else
    {
         //compare each player still playing to house
        for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)      
            if ( !(pPlayer->IsBusted()) )
            {
                if (pPlayer->GetTotal() > m_House.GetTotal())
                    pPlayer->Win();
                else if (pPlayer->GetTotal() < m_House.GetTotal())
                    pPlayer->Lose();
                else
                    pPlayer->Push();
            }
    }

    //remove everyone's cards
    for (pPlayer = m_Players.begin(); pPlayer != m_Players.end(); ++pPlayer)      
        pPlayer->Clear();
    m_House.Clear();
}

///
//genericPlayerImp.cpp
///
#include "genericPlayer.h"

#include <iostream>

using namespace std;

//overloads << operator so a GenericPlayer object can be sent to cout
ostream& operator<<(ostream& os, const GenericPlayer& aGenericPlayer)
{
    os << aGenericPlayer.m_Name << ":\t";
    
    vector<Card*>::const_iterator pCard;
    if (!aGenericPlayer.m_Cards.empty())
    {
        for (pCard = aGenericPlayer.m_Cards.begin(); 
             pCard != aGenericPlayer.m_Cards.end(); ++pCard)
            os << *(*pCard) << "\t";

        if (aGenericPlayer.GetTotal() != 0)
            cout << "(" << aGenericPlayer.GetTotal() << ")";
    }
    else
    {
        os << "<empty>";
    }
        
    return os;
}

GenericPlayer::GenericPlayer(const string& name): m_Name(name)
{}

GenericPlayer::~GenericPlayer()  
{}

bool GenericPlayer::IsBusted() const
{ 
    return (GetTotal() > 21);
}

void GenericPlayer::Bust() const
{
    cout << m_Name << " busts.\n";
}

///
//handImp.cpp
///
#include "hand.h"

Hand::Hand()
{
    m_Cards.reserve(7);
}

Hand::~Hand()  //don't use the keyword virtual outside of class definition
{
    Clear();
}

void Hand::Add(Card* pCard)
{
    m_Cards.push_back(pCard);
}
 
void Hand::Clear()
{
    //iterate through vector, freeing all memory on the heap
    vector<Card*>::iterator iter = m_Cards.begin();
    for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
    {
        delete *iter;
        *iter = 0;
    }
    //clear vector of pointers
    m_Cards.clear();
}

int Hand::GetTotal() const
{
    //if no cards in hand, return 0
    if (m_Cards.empty())
        return 0;
  
    //if a first card has value of 0, then card is face down; return 0
    if (m_Cards[0]->GetValue() == 0)
        return 0;
    
    //add up card values, treat each Ace as 1
    int total = 0;
    vector<Card*>::const_iterator iter;
    for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
        total += (*iter)->GetValue();
                  
    //determine if hand contains an Ace
    bool containsAce = false;
    for (iter = m_Cards.begin(); iter != m_Cards.end(); ++iter)
        if ((*iter)->GetValue() == Card::ACE)
            containsAce = true;
          
    //if hand contains Ace and total is low enough, treat Ace as 11
    if (containsAce && total <= 11)
        //add only 10 since we've already added 1 for the Ace
        total += 10;   
            
    return total;
}

///
//houseImp.cpp
///
#include "house.h"

House::House(const string& name): GenericPlayer(name)
{}

House::~House()
{}

bool House::IsHitting() const
{
    return (GetTotal() <= 16);
}   

void House::FlipFirstCard()
{
    if (!(m_Cards.empty()))
        m_Cards[0]->Flip();
    else cout << "No card to flip!\n";
}

///
//playerImp.cpp
///
#include "player.h"
#include "genericPlayer.h"
using namespace std;

Player::Player(const string& name): GenericPlayer(name)
{}

Player::~Player()
{}
    
bool Player::IsHitting() const
{
	cout << m_Name << ", do you want a hit? (Y/N): ";
    char response;
    cin >> response;
    return (response == 'y' || response == 'Y');
}

void Player::Win() const
{
    cout << m_Name <<  " wins.\n";
}

void Player::Lose() const
{
    cout << m_Name <<  " loses.\n";
}

void Player::Push() const
{
    cout << m_Name <<  " pushes.\n";
}
Topic archived. No new replies allowed.