尝试将std :: sort()与自定义对象一起使用

时间:2013-04-24 06:20:36

标签: c++ sorting object vector

我在网上查了几个教程。我已经尝试过了,但问题是std::sort()没有执行任何操作!这是我的全部代码:

#include <string>
#include <iostream>
#include <iomanip>
#include <sstream> 
#include <algorithm>
#include <vector>
using namespace std;

#ifndef _card_h
#define _card_h

enum Suit {
    CLUBS, DIAMONDS, HEARTS, SPADES
};

enum Rank {
    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
};

class Card {
    public:
        Card();
        Card(Rank, Suit);
        ~Card();
        Rank GetRank();
        Suit GetSuit();
        string ToString();
    private:
        Rank rank;
        Suit suit;
};
#endif

Card::Card() {
}

Card::Card(Rank rank, Suit suit) {
    this->rank = rank;
    this->suit = suit;
}

Card::~Card() {}

Rank Card::GetRank() {
    return rank;
}

Suit Card::GetSuit() {
    return suit;
}

string Card::ToString() {
    string cardName = "";
    switch (rank) {
        case TWO   : cardName += "2"; break;
        case THREE : cardName += "3"; break;
        case FOUR  : cardName += "4"; break;
        case FIVE  : cardName += "5"; break;
        case SIX   : cardName += "6"; break;
        case SEVEN : cardName += "7"; break;
        case EIGHT : cardName += "8"; break;
        case NINE  : cardName += "9"; break;
        case TEN   : cardName += "T"; break;
        case JACK  : cardName += "J"; break;
        case QUEEN : cardName += "Q"; break;
        case KING  : cardName += "K"; break;
        case ACE   : cardName += "A"; break;
    }
    switch (suit) {
        case CLUBS    : cardName += "C"; break;
        case DIAMONDS : cardName += "D"; break;
        case HEARTS   : cardName += "H"; break;
        case SPADES   : cardName += "S"; break;
    }
    return cardName;
}

#ifndef _cardcomparer_h
#define _cardcomparer_h

class CardComparer {  
    public:
        bool operator() (Card*, Card*);
    private:
        Card* firstCard;
        Card* secondCard;
};
#endif

bool CardComparer::operator() (Card* firstCard, Card* secondCard) {
    this->firstCard = firstCard;
    this->secondCard = secondCard;
    cout << "in Cardcompare! " << endl;
    if (firstCard->GetRank() == secondCard->GetRank()) {
        return firstCard->GetSuit() > secondCard->GetSuit();
    }
    else {
        return firstCard->GetRank() > secondCard->GetRank();
    }
}

#ifndef _hand_h
#define _hand_h
const int CARDS_IN_HAND = 5;
class Hand {
    public:
        Hand(int);
        ~Hand();
        void AddCard(Card*);
        string ToString();

    private:
        int cardCount;
        int playerID;
        vector<Card*> cards;

};
#endif

Hand::Hand(int playerID) {
    this->playerID = playerID;
    cards.reserve(CARDS_IN_HAND);
    cardCount = 0;
}

Hand::~Hand() {
    cards.clear();
}

void Hand::AddCard(Card* newCard) {
    cards[cardCount] = newCard;
    cardCount++;
    sort(cards.begin(), cards.end(),CardComparer());
}

string Hand::ToString() {
    stringstream playerCards;
    playerCards << "Player " << this->playerID << " -";
    for (int i = 0; i < cardCount; i++ ){
        playerCards << " " << cards[i]->ToString();
    }
    return playerCards.str();
}

int main() {
    vector<Hand*> hands;
    hands.reserve(1);
    hands[0] = new Hand(0);
    hands[0]->AddCard(new Card((Rank)4, (Suit)1));
    hands[0]->AddCard(new Card((Rank)8, (Suit)2));
    hands[0]->AddCard(new Card((Rank)5, (Suit)1));
    hands[0]->AddCard(new Card((Rank)2, (Suit)0));
    hands[0]->AddCard(new Card((Rank)7, (Suit)3));
    cout << hands[0]->ToString() << endl;
    return 0;
}

问题是第133行({​​{1}})没有执行。无论我是在评论中还是在结果中都没有改变,我甚至在93(sort(cards.begin(), cards.end(),CardComparer());)上添加了一个额外的行,如果它使用bool,它会输出一些内容。但事实并非如此。我找不到问题所在。这里有什么问题,如何解决?

2 个答案:

答案 0 :(得分:3)

问题是该向量不知道您尝试在AddCard中添加卡片,或者更准确地说,您没有真正添加这些卡片,因为您没有调用{ {1}}但只是将指针放在内存中的某处。是的,由于调用push_back,向量拥有该内存,但它认为它是空的。因此reservebegin()给出相同的迭代器,并对0个元素进行排序。

在您选择的教科书中查找有关end()和其他容器的章节。您无需跟踪卡片的数量(vector),因为如果正确使用,矢量可以完美地为您完成。

答案 1 :(得分:0)

您的代码存在许多需要解决的问题。其中一个最重要的事实是你正在泄漏大量内存。您声明vector<Card*>并分配内存但从未释放它。您在向量中输入数据的方式也不正确。保留函数实际上并不创建新元素,它只是为它们保留内存。

这是一个清理版本,包括让您的排序正常工作。希望通过研究它,你将学到一些关于C ++的东西。

#include <string>
#include <iostream>
#include <iomanip>
#include <sstream> 
#include <algorithm>
#include <vector>
#include <memory>
using namespace std;

enum Suit {
    CLUBS, DIAMONDS, HEARTS, SPADES
};

enum Rank {
    TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING, ACE
};
const char *card_lookup[] = {"2", "3", "4", "5", "6", "7", "8", "9", "T", "J", "Q", "K", "A"};
const char *suit_lookup[] = {"C", "D", "H", "S" };

class Card {
    public:
        Card::Card() 
        { }
        Card::Card(Rank rank, Suit suit) 
        {
            this->rank = rank;
            this->suit = suit;
        }
        Card::~Card() 
        {}
        Rank Card::GetRank() const
        {
            return rank;
        }

        Suit Card::GetSuit() const
        {
            return suit;
        }
        string Card::ToString() {
            string cardName = card_lookup[rank];
            cardName += suit_lookup[suit];
            return cardName;
        }
    private:
        Rank rank;
        Suit suit;
};

bool operator<(const Card& lhs, const Card& rhs)
{
    if(lhs.GetRank() == rhs.GetRank())
        return lhs.GetSuit() < rhs.GetSuit();
    else
        return lhs.GetRank() < rhs.GetRank();

}

const int CARDS_IN_HAND = 5;
class Hand {
    public:
        Hand::Hand(int playerID) 
        {
            this->playerID = playerID;
        }
        Hand::~Hand() 
        { }

        void Hand::AddCard(Card newCard) 
        {
            cards.push_back(newCard);
        }
        string Hand::ToString() 
        {
            sort(cards.begin(), cards.end());

            stringstream playerCards;
            playerCards << "Player " << this->playerID << " -";
            for (auto it = cards.begin(), end = cards.end(); it != end; ++it)
                playerCards << " " << it->ToString();

            return playerCards.str();
        }

    private:
        int playerID;
        vector<Card> cards;

};


int main() {
    vector<Hand> hands;
    Hand h(1);
    h.AddCard(Card(SIX, DIAMONDS));
    h.AddCard(Card(TEN, HEARTS));
    h.AddCard(Card(SEVEN, DIAMONDS));
    h.AddCard(Card(FOUR, CLUBS));
    h.AddCard(Card(NINE, SPADES));
    hands.push_back(h);
    cout << hands[0].ToString() << endl;
    return 0;
}