-4

I'm having an issue with inheritance in C++.

I have a "deckOfCards" object that I'm trying to inherit vector from. I'm doing this because I want the "deckOfCards" object itself to be a collection.

Only issue is the code won't let me add objects using the "this" keyword unless I inherit from "vector card* " not "vector Card".

Here is the class code for "deckOfCards":

#include "stdafx.h"
#include <vector>
#include <typeinfo>
#include <iostream>
//#include "Card.cpp"

using namespace System;
using namespace System::Collections::Generic;
using namespace std;

/// <summary>
/// Deck of cards class
/// </summary>
/// 
/// 
/// 
public enum deckTypeEnum { Full = 1 };
public enum cardSuit { Hearts = 1, Diamonds = 2, Clubs = 3, Spades = 4 };
public enum cardRank { Ace = 1, Two = 2, Three = 3, Four = 4, Five = 5, Six = 6, Seven = 7, Eight = 8, Nine = 9, Ten = 10, Jack = 11, Queen = 12, King = 13 };


public class Card
{
    public: Card(cardSuit suit, cardRank rank)
    {
        CardSuit = suit;
        CardRank = rank;
}

    public: cardSuit CardSuit;
    public: cardRank CardRank;
};

public class DeckOfCards: public vector<Card*>
{
    public:DeckOfCards::DeckOfCards(deckTypeEnum deckType)
    {
        InitCardDeck(deckType);
    }

    public: void InitCardDeck(deckTypeEnum deckType)
    {
    this->push_back(new Card(Hearts, Four));
    switch (deckType)
        {
            case 1:
                CardCount = 52;
                GetFullCardDeck();
                break;
            default:
                CardCount = 52;
                GetFullCardDeck();
                break;
        }
}

    public: void GetFullCardDeck()
    {
        for (int i=0; i<Spades; i++)
        {
            for (int g=0; g<King; g++)
            {
            this->push_back(new Card((cardSuit)i, (cardRank)g));
            }
        }
    }

   public: void Shuffle()
   {
        Random^ rand = gcnew Random();
        for (int i = CardCount - 1; i > 0; i--)
        {
            int n = rand->Next(i + 1);
        Card *temp = this->at(i);
            this->at(i) = this->at(n);
            this->at(n) = temp;
        }
    }

    public: int CardCount;
    //   public: vector<Card> deckocards1;
//deckocards1[1];
};

This presents a problem later on where I'm moving 5 objects from the "deckOfCards" object to another vector (player.CardHand). The vector (player.CardHand) is of type "vector Card". So it doesn't match the "deckOfCards" type of "vector Card* ". I get an error as a result.

move(deckOfCards.begin(), it, back_inserter(player.CardHand));  // ##

An easy resolution would be to make Player.Hand of type "vector Card" and not "vector Card* ".

The reason Player.Hand has to be of type "vector Card" and not "vector Card* " is because I need to do a switch statement on each items in the collection and if it is "vector Card* " I get the error "expression must have class type".

public: int GetScore(vector<Card> cardHand)
{
    int score = 0;

    for (int i=0;i<cardHand.size();i++)
    {
        switch (cardHand[i].CardRank)
        {
            case King:
                score += 10;
                break;
            case Queen:
                score += 10;
                break;
            case Jack:
                score += 10;
                break;
            //Considering an Ace is equal to one, it doesn't mention it in the instructions.
            default:
                score += (int)cardHand[i].CardRank;
                break;
        }
    }

    return score;
}

Edit

To simplify the question the issue I'm having is here:

I'm getting an error saying expression must have class type on the "CardHand" object.

public: int GetScore(vector<Card*> cardHand)
{
    int score = 0;

    for (int i=0;i<cardHand.size();i++)
    {
        switch (cardHand.CardRank)
        {
            case King:
                score += 10;
                break;
            case Queen:
                score += 10;
                break;
            case Jack:
                score += 10;
                break;
            //Considering an Ace is equal to one, it doesn't mention it in the instructions.
            default:
                score += (int)cardHand[i].CardRank;
                break;
        }
    }

    return score;
}
JBentley
  • 6,099
  • 5
  • 37
  • 72
mgmedick
  • 686
  • 7
  • 23
  • 3
    From a design standpoint, I think you have it a little off. Have you thought about designing it such that a `DeckOfCards` contains a `std::vector` rather than inherit from `std::vector`? Also - you're not using straight C++, your usage of `^` and `gcnew` point to Microsoft's C++-CLI. – wkl Jun 06 '14 at 18:32
  • Yea but I was thinking it was a classier answer to inherit from vector Card, because deckOfCards is actually a collection after all. – mgmedick Jun 06 '14 at 18:36
  • 2
    The standard library containers are not designed for use as base classes. For example, they do not have virtual destructors. – Fred Larson Jun 06 '14 at 18:38
  • 1
    @fonZ No, the tags are not right. It is not C++, at least the first code sample isn't. – juanchopanza Jun 06 '14 at 18:43
  • Have the PlayerHand use vector. Change GetScore to: int GetScore(vector& cardHand); because passing it in as a reference is much more efficient. Finally, change your switch to: switch (cardHand[i]->CardRank) (and of course make sure it's not null). – Jason Jun 06 '14 at 18:44
  • @fonz Doesn't look like C++ to me. – JBentley Jun 06 '14 at 18:53
  • @mgmedick While you can certainly mix C++ and C++/CLI code, it does not make much sense that you are using C++/CLI only for random numbers. – crashmstr Jun 06 '14 at 18:55
  • While the code has some C++/CLI, the problem is more of a C++ problem relating to inheriting from `std::vector`. – crashmstr Jun 06 '14 at 18:56
  • Its a CLI c++ console project, and I have gotten it to build – – mgmedick Jun 06 '14 at 19:07
  • I would suggest having a look at [Subclass/inherit standard containers?](http://stackoverflow.com/q/6806173/1227469), [Thou shalt not inherit from std::vector](http://stackoverflow.com/q/4353203/1227469), and [Why should one not derive from c++ std string class?](http://stackoverflow.com/q/6006860/1227469) (the latter is about `std::string` but the principle is the same), to make sure you have made the right decision. – JBentley Jun 06 '14 at 19:09
  • @crashmstr good point, I do remember that's why I went CLI, thinking it still was justified as C++. Again i'm pretty new to the C++ world, so this tidbit of info helps. Once I figure out this issue ill put it back into a c++ project and find something to do about the random – mgmedick Jun 06 '14 at 19:10
  • yea I can't get push_back() to work on vector it says the object needs to be of type vector – mgmedick Jun 06 '14 at 19:13

1 Answers1

0

I was eventually able to inherit from the normal vector<card>


The issue was this line of code:

this->push_back(new Card((cardSuit)i, (cardRank)g));

I ended up doing this:

Card blah = Card((cardSuit)i, (cardRank)g);
this->push_back(blah);

Once I was able to inherit from vector<card> and not vector<card*>, I was able to do what I needed.

mgmedick
  • 686
  • 7
  • 23