重载不编译的C ++继承?

时间:2016-02-13 00:51:43

标签: c++ inheritance overloading poker

我正在用C ++制作扑克游戏,我只是想开始吧。 我需要能够比较" Hands",以查看哪一个更大,相等或更小。 所以,我现在有一个Hand类,我创建了另外两个名为Straight和ThreeOfKind的子类(稍后我会添加其余的子类)。 Hand类有一个名为compareTo(Hand* otherHand)的方法,然后检查手的排名以查看哪个更好。此外,对于Straights和Three of a Winds,当它们具有相同的等级时,您可以将它们进行比较。就像直道和三种有三种类型的直道。

我今天写了一些初始代码,问题是,当我试着打电话给" Hand'" compareTo(Hand* otherHand)方法并传入Hand,Straight或Three of kind,编译器抱怨它试图强迫我使用Straight的compareTo(Straight* otherStraight)方法。所以,我应该超载,但它不起作用。

所以在继承完成后的Straight类中,我们应该有这两个方法:

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

基本上我在Hand类中有一个字段,将这些排名存储为整数。你知道吗。

最后,这是编译器错误消息:

  

错误C2664:&#39; int Straight :: compareTo(Straight )&#39;:无法从&#39; ThreeOfKind &#39;转换参数1到&#39;直接*&#39;

1 个答案:

答案 0 :(得分: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();  
};

这简化了Hand比较的方式:

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;
}

让你在Straight中定义它:

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

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