本文介绍了带有重载的C ++继承无法编译?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用C ++制作扑克游戏,而我只是想开始.我需要比较手"的能力,看看哪个更大,相等或更小.因此,我现在有一个Hand类,并且制作了另外两个子类,分别称为Straight和ThreeOfKind(稍后将添加其余的子类.Hand类有一个名为compareTo(Hand* otherHand)的方法,它随后检查手的排名以查看哪个更好.此外,使用直线"和三个同类",可以将它们在相同等级时进行比较.就像有直线的直线和有三种的直线.

I am making a Poker game in C++, and I am just trying to get started.I need the ability to compare "Hands", to see which one is greater, equal, or lesser.So, I have a Hand class now, and I made two other sub-classes that are called Straight and ThreeOfKind (I will add the rest later.The Hand class has a method called compareTo(Hand* otherHand), it then checks the hand ranking to see which one is better. Also, with the Straights and Three of a Kinds, you can compare them together when they are of the same rank. Like Straights with Straights and Three of a Kinds with Three of a Kinds.

我今天写了一些初始代码,而我的问题是,当我尝试调用"Hand's" compareTo(Hand* otherHand)方法并传入"Hand","Straight"或"Kind of a kind of kind"时,编译器抱怨,因为它试图强制执行我使用Straight的compareTo(Straight* otherStraight)方法.因此,我应该有重载,但是它不起作用.

I wrote some initial code today, and my problem is, when I try to call "Hand's" compareTo(Hand* otherHand) method and pass in a Hand, Straight, or Three of a Kind, the compiler complains as it is trying to force me to use the Straight's compareTo(Straight* otherStraight) method. So, I should have overloading, but it's not working.

因此,在Straight类中,继承完成后,我们应该具有以下两种方法:

So in the Straight class after inheritance is done, we should have these two methods:

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!

这是所有源代码...

Here is all the source code...

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

此外,这是手牌排名的列表:

Also, here is a list of the hand rankings:

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类中有一个字段,将这些排名存储为整数.就是这样.

Basically I have a field in the Hand class that stores these rankings as integers. Just so you know.

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

Lastly, this is the compiler error message:

推荐答案

编译器将查找compareTo方法,在Straight中找到它,而不查看Hand.如果添加适当的using语句,则可以告诉它查看Hand的compareTo来完成重载.

The compiler looks for a compareTo method, finds it in Straight, and doesn't look at Hand. If you add an appropriate using statement, you can tell it to look at Hand's compareTo as well to accomplish your overloading.

class Straight : public Hand {
private:
    int highCard;

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

    Straight(int aHighCard);
    Straight();

    int getHighCard();

    int compareTo(Straight* otherStraight);
};

建议您使用getRanking()来比较不同手型的手,而不是这样做,并定义被子类覆盖的getTieBreaker()以处理相同手型的情况.

Instead of doing this, I'd recommend you use getRanking() for comparison between hands of different hand types, and define getTieBreaker() overridden by subclasses to handle cases of the same type of hand.

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

这简化了Hand比较的方式:

This simplifies how Hand compares:

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

这篇关于带有重载的C ++继承无法编译?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-13 23:18