0

我有一个如下所述的课程

class Investment
{
private:
    void init(BWAPI::UnitType type1, BWAPI::UpgradeType type2, BWAPI::TechType type3, int numOfItems);
    UpgradeType upgradeType;
    TechType techType;
    UnitType unitType;

我的init方法就是这样

void Investment::init(BWAPI::UnitType type1, BWAPI::UpgradeType type2, BWAPI::TechType type3, int numOfItems)
{
    if (type1 != NULL) {

        this->unitType = type1;
        this->type = type1.isBuilding() ? BUILDING_TYPE : UNIT_TYPE;

    } else if (type2 != NULL) {

        this->upgradeType = type2;  
        this->type = UPGRADE_TYPE;

    } else if (type3 != NULL) {

        this->techType = type3; 
        this->type = TECH_TYPE;
    }

    this->numOfItems = numOfItems;
}

我以这种方式得到我的物品(只能是三种可能类型中的一种)

const void* Investment::getItem() const
{
    if (unitType != NULL)
        return &unitType;
    else if (upgradeType != NULL)
        return &upgradeType;
    else if (techType != NULL)
        return &techType;

    return NULL;
}

但是当我使用UnitType* type = (UnitType*) investment->getItem();指针获取项目时会发生什么失去它的价值

当我调用type->getName().c_str();它时返回一个空字符串

为了获得投资,我调用了一个 Stack 方法

// I have a stack of type std::vector<T*> stack;

T* getNext() {

    clear();

    for (int i = 0, leni = stack.size(); i < leni; i++) {

        T* t = stack.at(i);

        if (!t->isDone() && !t->isCanceled())
            return t;
    }

    return NULL;
}
4

3 回答 3

2

Investment我认为你可以通过让类持有一个(最好是smart)指向Type基类的指针来大大简化问题。在这个例子中,我使用了一个在Investment析构函数中被删除的原始指针,但如果想将类型的生命周期从Investment.

class InvestmentType { // some public virtual methods };

class UpdgadeType : public InvestmentType { /* Implement InvestmentType methods*/ };
class TechType : public InvestmentType { /* Implement InvestmentType methods*/ };
class UnitType : public InvestmentType { /* Implement InvestmentType methods*/ };

class Investment
{
 private:
    void init(const InvestmentType&  type, int numOfItems) : nItems_(numOfItems), type_(new type) {}
    int nItems_;
    InvestmentType* type_;
    ~Investment() { delete type_; }
 public:
    const InvestmentType* getItem() const { return type_; }
};
于 2012-12-11T07:17:56.057 回答
1

只是快速浏览一下代码就让我怀疑......使用的类型(即UpgradeTypeTechTypeUnitType)是指针吗?它看起来不像那样,因为您使用 address-of 运算符在getItem.

如果它们不是指针,则不能将它们与 进行比较NULL,因为非指针从不 NULL。这意味着总是getItem会返回一个指向变量的指针。unitType

我建议您重新设计,正如 juanchopanza 的回答中所建议的那样。

于 2012-12-11T08:52:16.347 回答
0

由于您无法按照建议进行重构,因此您应该根据您在函数type中分配的成员检查需要返回的类型。init()我认为这会起作用,但是您没有显示type定义的位置:

const void* Investment::getItem() const
{
    switch(type)
    {
        case BUILDING_TYPE:
        case UNIT_TYPE:
           return &unitType;
        case UPGRADE_TYPE:
           return &upgradeType;
        case TECH_TYPE:
           return &techType;
    }

    return NULL;
}

然而,这样做意味着调用者getItem()必须能够执行适当的向下转换。鉴于您没有明确提供此内容,这将成为代码用户混淆的持续来源。

然而:

如果您四处走动void*并期望您的类的用户向下转换为正确的类型,这几乎总是表明C++. 正确的方法是将其重构为适当的多态类层次结构,正如@juanchopanza 在他的回答中所建议的那样。

于 2012-12-11T19:19:37.370 回答