2013-07-19 50 views
3

我是C++的新手,我正在编写一个简单的代码来比较一个名为Comparable的父类的子类的两个对象。我想每个子类有它自己实现一个比较基础上,他们持有的数据对象的方法,所以我用虚拟关键字:虚拟功能实现C++不工作

class Comparable { 
public: 
virtual int compare(Comparable *other); 
    }; 

例如,我的子类HighScoreElement将有自己的执行比较是的会将对象的分数与另一个HighScoreElement的分数进行比较。

这里是我的子类HighScoreElement:

class HighScoreElement: public Comparable { 
     public: 
virtual int compare(Comparable *other); 
HighScoreElement(string user_name, int user_score); // A constructor 
     private: 
int score; 
string name; 

}; 

但在我HighScoreElement比较实施,我第一次尝试检查当前对象的数据是一样的其他数据。但是由于指向其他类的指针是Comparable类而不是HighScoreElement,因此即使HighScoreElement是Comparable的子类,我也无法在代码中引用other->分数。

这是迄今为止全码:

#include <iostream> 
using namespace std; 

class Comparable { 
public: 
virtual int compare(Comparable *other); 
    }; 

class HighScoreElement: public Comparable { 
public: 
    virtual int compare(Comparable *other); 
    HighScoreElement(int user_score, string user_name); 
private: 
    string name; 
    int score; 
}; 

HighScoreElement::HighScoreElement(int user_score, string user_name) { 
name = user_name; 
score = user_score; 
} 



int HighScoreElement::compare(Comparable *other) { 
if (this->score == other->score) { // Compiler error right here, other->score is invalid. 
    // Code to do the comparing if two scores are equal... 
} 
} 

我立即得到一个编译错误,当我写这篇文章的代码:

if (this->score == other->score) 

因为其他没有数据称为比分,但其子类HighScoreElement的确如此。如何修复我的函数实现,以便可以引用“其他”的数据?我知道我的问题可能听起来含糊不清,但任何帮助将不胜感激!

+0

一个简单的解决办法是使用'的dynamic_cast (其他)',它返回'nullptr'('0')的情况下,'other'不指向HighScoreElement'的'的实例(或从中得出)。不过,可能有更好的设计,但不包括'dynamic_cast'。 – dyp

+2

没有什么个人的,但这个代码是丑陋的。看起来像Comparable作为接口的某种java风格的c + +代码?我的心碎了。 – kvv

+0

@kw当我开始使用C++时,我的代码非常糟糕。=)学习过程是一条泥泞的道路。随着时间的推移,人们的代码质量会提高。 –

回答

1

您可以在基类中实现一个虚拟函数GetScore(),可能是pure virtual,并使用该函数代替比较函数中的字段分数。使其成为一种常量方法。在另一方面,比较可能是在基类中实现的方法,使用this->GetScore()other->GetScore()

代码存根:

class A { 
    virtual int getScore() const = 0; 
    inline bool compare(const A* in) {return (in && this->getScore() == in->getScore());} 
    //return false also if "in" is set to NULL 
    } 


class B : public A { 
    int score; 
    inline int getScore() const {return score;} 
    } 
+0

感谢您的输入!现在我可以看到我应该如何实施它。 – ra1nmaster

+0

@ Ra1nMaster欢迎您!如果您愿意,您可以决定[接受其中一个答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Antonio

+0

我重写了我的代码,以便其他人可以采用一个纯粹的虚拟getScore函数,它将返回适当的分数值。 – ra1nmaster

-1

你确定这不是

比较(可比其他

If(this-> score == other.score

+0

“Comparable”不包含名为'score'的成员,并且您的建议会对从“Comparable”派生的所有传入对象进行切片。 – dyp

+0

嗯,我认为这里有些困惑。 OP可能会混淆实现Comparable接口和使用Comparable作为传递的类型。 –

0

您可以使用“dynamic_cast”强制传递给HighScoreElement :: compare的指针(它在失败时抛出bad_cast异常)。

int HighScoreElement::compare(Comparable *other) { 
HighScoreElement *h = NULL; 
try 
{ 
    ptr = dynamic_cast<HighScoreElement *>(other); 
} 
catch(std::bad_cast const &) 
{ 
    // Handle the bad cast... 
} 
if (this->score == ptr->score) { 
// Code to do the comparing if two scores are equal... 
} 
} 
+0

[expr.dynamic.cast]/9“指针类型失败转换的值是所需结果类型的空指针值。失败 强制转换为引用类型抛出异常[0123]” – dyp

+0

@DyP :是的,谢谢你的澄清。 – SeaBass

+0

@SeaBass你的回答是错误的。 – BlackMamba

0

如果您准备接受空指针,则可以使用动态转换。当您比较HighScoreElement指针以避免不必要的转换时,可以对案例负载过重。

#include <iostream> 
using namespace std; 

class Comparable { 
public: 
    virtual int compare(Comparable *other) = 0; // made pure virtual to compile without definition 
}; 

class HighScoreElement: public Comparable { 
public: 
    virtual int compare(Comparable *other); 
    int compare(HighScoreElement *other); // comparing to a HighScoreElement ptr, no need to dynamic cast 
    HighScoreElement(int user_score, string user_name); 
private: 
    string name; 
    int score; 
}; 

HighScoreElement::HighScoreElement(int user_score, string user_name) { 
    name = user_name; 
    score = user_score; 
} 

int HighScoreElement::compare(Comparable *other) { 
    HighScoreElement * pHSE = dynamic_cast<HighScoreElement*>(other); 
    if (pHSE) { 
    return compare(pHSE); 
    } else { 
    return -1; // or however you want to handle compare to non HighScoreElement 
    } 
} 

int HighScoreElement::compare(HighScoreElement *other) { 
    if (this->score == other->score) { 
    ; 
    } 
} 
+0

@DyP谢谢。似乎我从来没有100%的权利。更正 –

+1

没有人会获得所有东西总是100%正确;) – dyp

+0

请注意,您还应该更改代码,它当前包含可能的访问冲突(因为没有例外,'other-> score'可能在nullptr上运行)。派遣很好,如果'dynamic_cast'返回'0',那么这些对象是不相等的。但是请注意'other'可能来自'HighScoreElement',因此只有检查'score'可能不够。 – dyp