2016-02-13 95 views
2

我正在用C++製作撲克遊戲,我只是想開始。 我需要能夠比較「手」,看哪一個更大,相等或更小。 因此,我現在有一個Hand類,並且我創建了另外兩個子類,分別稱爲Straight和ThreeOfKind(我將在後面添加其他類 Hand類有一個名爲compareTo(Hand* otherHand)的方法,然後檢查手的排名以查看哪一個更好,另外,在Straights和Three of a Kinds中,你可以將它們在同一級別進行比較,就像Straights with Straights和Three of a Kinds with Three of Kinds一樣重載C++繼承不編譯?

我寫了今天有一些初始代碼,而我的問題是,當我嘗試調用「Hand」的方法並傳入一種Hand,Straight或Three時,編譯器會抱怨,因爲它試圖強制我使用Straight的方法compareTo(Straight* otherStraight)所以,我應該超載,但它不起作用。

所以在繼承後的直類完成後,我們應該有這兩種方法:

int Hand::compareTo(Hand* otherHand); 
int Straight::compareTo(Straight* otherStraight); 

// But, if you do this, it works: 
Straight myStraight1 = new Straight(7); 
Straight myStraight2 = new Straight(5); 
myStraight1.compareTo(myStraight2); 
// This is valid... 

// If you do this, then the compiler complains! 
Straight myStraight3 = new Straight(10); 
ThreeOfKind myTrips4 = new ThreeOfKind(3); 
myStraight3.compareTo(myTrips4); 
// This above line complains that you cannot convert a ThreeOfKind to a Straight 
// Even though I am trying to use Hand's compareTo(Hand* otherHand) method and 
// cast a Three of a Kind to a Hand object, 
// it fails with the overloading! 

這裏是所有的源代碼...

////////////////////////// 
// C++ main header file // 
////////////////////////// 


#pragma once 


class Hand { 

private: 
    int ranking; 

public: 
    Hand(int aRanking); 
    Hand(); 

    int getRanking(); 

    int compareTo(Hand* otherHand); 
}; 

class Straight : public Hand { 

private: 
    int highCard; 

public: 

    Straight(int aHighCard); 
    Straight(); 

    int getHighCard(); 

    int compareTo(Straight* otherStraight); 
}; 

class ThreeOfKind : public Hand { 

private: 
    int tripsValue; 

public: 

    ThreeOfKind(int aTripsValue); 
    ThreeOfKind(); 

    int getTripsValue(); 

    int compareTo(ThreeOfKind* otherThreeOfKind); 
}; 


/////////////////////////// 
// C++ main .cpp file... // 
/////////////////////////// 
#include <iostream> 
#include "PokerTest1.h" 
using namespace std; 

Hand::Hand(int aRanking) { 

    this->ranking = aRanking; 
} 

Hand::Hand() { 

    this->ranking = 0; 
} 

int Hand::getRanking() { 
    return this->ranking; 
} 

int Hand::compareTo(Hand* otherHand) { 

    cout << "COMPARING HANDS..." << endl; 

    if (this->getRanking() < otherHand->getRanking()) { 

     cout << "HANDS RETURNING -1..." << endl; 

     return -1; 
    } 
    else if (this->getRanking() > otherHand->getRanking()) { 

     cout << "HANDS RETURNING 1..." << endl; 

     return 1; 
    } 

    cout << "HAND RANKINGS ARE EQUAL..." << endl; 

    if (this->getRanking() == 4 && otherHand->getRanking() == 4) { 

     cout << "HANDS ARE BOTH STRAIGHTS..." << endl; 

     Straight* myStraight1 = (Straight*)this; 
     Straight* myStraight2 = (Straight*)otherHand; 

     cout << "COMPARING BOTH STRAIGHTS..." << endl; 

     return myStraight1->compareTo(myStraight2); 
    } 
    else if (this->getRanking() == 3 && otherHand->getRanking() == 3) { 

     cout << "HANDS ARE BOTH THREE OF A KINDS..." << endl; 

     ThreeOfKind* myTrips1 = (ThreeOfKind*)this; 
     ThreeOfKind* myTrips2 = (ThreeOfKind*)otherHand; 

     cout << "COMPARING BOTH TRIPS..." << endl; 

     return myTrips1->compareTo(myTrips2); 
    } 

    return 0; 
} 

Straight::Straight(int aHighCard) : Hand(4) { 
    this->highCard = aHighCard; 
} 

Straight::Straight() : Hand(4) { 
    this->highCard = 0; 
} 

int Straight::getHighCard() { 
    return this->highCard; 
} 


int Straight::compareTo(Straight* otherStraight) { 

    cout << "INSIDE STRAIGHT COMPARE TO..." << endl; 

    if (this->highCard < otherStraight->highCard) { 

     cout << "STRAIGHT COMPARE RETURNING -1..." << endl; 

     return -1; 
} 
    else if (this->highCard > otherStraight->highCard) { 

     cout << "STRAIGHT COMPARE RETURNING 1..." << endl; 

     return 1; 
    } 

    cout << "STRAIGHT COMPARE RETURNING 0..." << endl; 

    return 0; 
} 


ThreeOfKind::ThreeOfKind(int aTripsValue) : Hand(3) { 
    this->tripsValue = aTripsValue; 
} 

ThreeOfKind::ThreeOfKind() : Hand(3) { 
    this->tripsValue = 0; 
} 

int ThreeOfKind::getTripsValue() { 
    return this->tripsValue; 
} 

int ThreeOfKind::compareTo(ThreeOfKind* otherThreeOfKind) { 

    cout << "INSIDE STRAIGHT COMPARE TO..." << endl; 

    if (this->tripsValue < otherThreeOfKind->tripsValue) { 

     cout << "TRIPS COMPARE RETURNING -1..." << endl; 

     return -1; 
    } 
    else if (this->tripsValue > otherThreeOfKind->tripsValue) { 

     cout << "TRIPS COMPARE RETURNING 1..." << endl; 

     return 1; 
    } 

    cout << "TRIPS COMPARE RETURNIN 0..." << endl; 

    return 0; 
} 

int main() 
{ 

    // Test the classes... 
    // with Straight compared to a Three of a Kind. 
    // Should try to invoke Hand::compareTo(Hand* otherHand) { ... }; 
    // But, instead, it try to invoke Straight::compareTo(Straight* otherStraight) { ... }; 

    // If you put both these methods in the Straight class (rather than using inheritence, it works) 
    // If you delete Straight::compareTo(Straight* otherStraight) { ... }, the line below compiles 

    // It is just strange why it won't compile... 
    Straight* myStraightA = new Straight(9); // Straight of 5, 6, 7, 8, 9 
    ThreeOfKind* myTripsB = new ThreeOfKind(2); // Three of a Kind of 2, 2, 2 

    cout << "Compare results..." << endl; 
    cout << myStraightA->compareTo(myTripsB) << endl; // Compiler error... 

    return 0; 
} 

而且,這裏是一個列表手排名:

0 → high card 
1 → pair 
2 → two pair 
3 → three of a kind 
4 → straight 
5 → flush 
6 → full house 
7 → quads 
8 → straight flush 
9 → royal flush 

基本上我有在存儲這些排名爲整數手類中的字段。就這樣你知道。

最後,這是在編譯器錯誤消息:

錯誤C2664: 'INT直::的compareTo(直)':不能從轉換參數1 'ThreeOfKind' 到 '直*'

+0

'直myStraight3 =新直(10);'應該編譯失敗 –

+2

拋開你的問題,類和子類並不是真正用代碼模擬這種方法的好方法。如果你有一堆牌,你必須首先確定這是什麼樣的牌,然後實例化一個合適類型的對象,這有點奇怪,特別是當你可以繪製或改變牌時,從而「改變對象類型」。另外,你的用於比較不同牌的代碼將會混亂地分佈在幾個類中,這使得很難弄清楚發生了什麼。 – Sarien

+1

這段代碼的方式和方式比它所需要的複雜,當你嘗試向代碼中添加更多的案例時,這樣的問題會越來越頻繁。 –

回答

3

You are trying to overload across classes.

編譯器查找一個compareTo方法,發現它在Straight,不看Hand 。如果你添加一個合適的using聲明,你可以告訴它看Hand的compareTo以完成你的重載。

class Straight : public Hand { 
private: 
    int highCard; 

public: 
    using Hand::compareTo; // <<< HERE 

    Straight(int aHighCard); 
    Straight(); 

    int getHighCard(); 

    int compareTo(Straight* otherStraight); 
}; 

而不是做這個的,我建議你使用getRanking()針對不同類型的手手中的比較,並定義getTieBreaker()被子類覆蓋,以處理同一類型的手的情況。

class Hand { 
public: 
    int getRanking(); 
    // virtual causes subclass' version to be called if done from reference or pointer. 
    virtual int getTieBreaker(); 
}; 

這簡化了手如何比較:

int Hand::compareTo(Hand* otherHand) { 
    if (this->getRanking() < otherHand->getRanking()) { 
     return -1; 
    } 
    else if (this->getRanking() > otherHand->getRanking()) { 
     return 1; 
    } 

    if (this->getTieBreaker() < otherHand->getTieBreaker()) { 
     return -1; 
    } 
    else if (this->getTieBreaker() > otherHand->getTieBreaker()) { 
     return 1; 
    } 
    return 0; 
} 

,讓你在直線定義它:

class Straight : public Hand { 
//... 
public: 
    int getHighCard(); 
    int getTieBreaker(); 
}; 

int Straight::getTieBreaker() { 
    return this->highCard; 
}