2016-02-13 97 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; 
}