3

I have an object of a Deck class which contains a dynamically allocated array of pointers to objects of another class, PlayingCard. I'm attempting to overload the << operator (as a friend of class Deck) to output details of each card in a Deck object iteratively. At present the overload definition looks like this:

ostream& operator<< (ostream& out, const Deck& d)
{
    PlayingCard** pCards = d.getPlayingCards();
    for(int i = 0; i < d.getTotalCards(); ++i)
    {
        out << pCards[i] << endl;
        // the << operator is also overloaded in the PlayingCard class to take PlayingCard objects as arguments.
        // the overload in the PlayingCard class definitely works.
    }

    return out;
}

When attempting to construct a Deck object and output its card details, it outputs a list of memory addresses rather than actual data, so I guess I need to dereference pCards[i]. When I try to do that, however, the output is garbage and I eventually reach an access violation in the debugger. I've tried all of the following combos, but all cause either compile-time or run-time problems:

*pCards[i], pCards[i]*, (*pCards[i]), *(pCards[i])

Is this just incorrect syntax for dereferencing a pointer that's within an array, or is there something deeper I'm not understanding here? How can I rewrite this code so the program outputs the actual data held by these PlayingCard objects, rather than just the memory addresses?

  • the problem is probably in getPlayingCards... – Karoly Horvath Feb 04 '12 at 20:52
  • Have you considered using an iterable container like std::vector or std::set instead. At least that way you can just have a getter to the start iterator of the collection and just iterate through -- at least that way you wouldn't even have to worry about pointers (this, of course, makes certain assumptions about the availability of the copy constructor for PlayingCard)... Better yet, you could also use a Visitor design pattern to traverse the collection of PlayingCard objects, keeping the traversal logic in the Deck object... – hatboyzero Feb 04 '12 at 21:01

2 Answers2

1

*pCards[i], (*pCards[i]) and *(pCards[i]) are all dereferencing the objects. There is something else going wrong in another part of your program, probably in the implementation of Deck.

Georg Fritzsche
  • 97,545
  • 26
  • 194
  • 236
0
ostream& operator<< (ostream& out, const Deck& d)
{
    PlayingCard** pCards = d.getPlayingCards();
    for(int i = 0; i < d.getTotalCards(); ++i)
        out << (*(pCards[i])) << endl;  
    return out;
}

You are passing pCards[i] which is a pointer to PlayingCard ( = PlayingCard *). There won't be operator<< method overloaded for that so you need *(pCards[i]) but then you must also ensure that you have the commensurate overloading for class PlayingCard. ie a friend function with signature:

ostream& operator<< (ostream& out, const PlayingCard& d);

Oops, just read your comments:

        // the << operator is also overloaded in the PlayingCard class to take PlayingCard objects as arguments.
        // the overload in the PlayingCard class definitely works.

Are you sure that method is visible to the function you have shown code for above?

John
  • 6,433
  • 7
  • 47
  • 82
  • That is a very good question, and I'm not sure. I have ostream& operator<< (ostream& out, const PlayingCard& pc) as a friend function of the PlayingCard class. PlayingCard is then forward-declared in the header file for Deck, and finally the headers for both classes are included in the source file for Deck. – Ryan Loughborough Feb 04 '12 at 21:04