我是C++的新手,所以我决定创建一个纸牌游戏。我想将派生的卡片对象作为卡片*存储在向量中。当有人画一张卡片时,我想从向量中取出第一个对象并返回它。这是事情变得棘手的地方,当我这样做时,我想把它从Card*转换回它原来的派生类型。我读到,在c++中没有明确的转换是不可能的,我想要么重申这一点,要么找到解决方案。
卡片类
class Card
{
public:
int Cost;
string Name;
string Description;
Card() {}
Card(int Cost, string Name, string Description) : Cost(Cost), Name(Name), Description(Description) {}
};灵魂阶级
class Soul : public Card
{
public:
int Attack;
int Defense;
Soul(int Cost, string Name, string Description, int Attack, int Defense) :Card(Cost, Name, Description), Attack(Attack), Defense(Defense) {}
void Attacking(Soul* DefendingSoul);
};最后是一个特定卡片类的示例。
class Fire_Spirit : public Soul
{
public:
Fire_Spirit() : Soul(1, "Fire Spirit", "A lonely spirit born from the inferno.", 2, 1) {}
~Fire_Spirit();
};甲板级
class Deck
{
public:
Deck();
~Deck();
Card* Draw();
void Shuffle();
void Add(Card* cardToAdd);
void PrintDeck();
static vector<Card*> Cards;
};绘制法
auto Deck::Draw() -> Card*
{
auto temp = Cards.front();
Cards.erase(Cards.begin());
return temp;
}理想情况下,我只想在这里返回auto,但我读到我需要为方法定义返回类型的auto (我希望不这样显示)
我想从卡*到Fire_Spirit(*?)或者任何其他特定的卡类。我知道我可以做一个巨大的转换声明,但必须有一个更好的方法吗?
发布于 2016-04-14 04:27:33
根据评论中提供的反馈,我会提出这样的解决方案:
class Card {
private:
CardKind kind_;
std::fucntion<void (Card &)> attack_;
std::function<void (Card &)> effectFunc_;
std::unordered_map<std::string, boost::any> properties;
Card(CardKind kind, std::function<void (Card &)> attackFunc,
std::function<void (Card &)> effectFunc);
};发布于 2016-04-14 03:10:29
按指针存储在容器中会导致类型信息在您将类型放入容器时丢失。类型擦除的要点正是以统一的方式处理元素,而类层次结构就是这样做的。
如果您想要返回类型信息,则需要使用typeid(my_var)或dynamic_cast询问运行时。确保基类具有虚拟析构函数。这将为您提供原始类型:
auto temp = cards.front();
if (typeid(temp) == typeid(MyDerivedCard)) {
}
else if (...) {
}或
if ((MyDerivedCard * c = dynamic_cast<MyDerivedCard>(temp)) != nullptr) {
//Use derived
}
...P.S.:你可以用std::unique_ptr<Card>来存储卡片。它们将自动删除内存并清除所有权。在ptr了解它
https://stackoverflow.com/questions/36613102
复制相似问题