2012-12-11 195 views
0

我得到了如下C++的指針失去指針引用

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();它返回一個空字符串

獲得投資我所說的堆疊的方法

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

代碼的顯示使用 –

+0

有人能幫助????? – thiagoh

+0

爲什麼'GETNEXT()''調用清除()'? 'clear()'做什麼?你知道一個事實,即'investment.getItem()'應該返回一個'UnitType',而不是其他的東西(像'UpgradeType'或'TechType')?你怎麼知道這一點? – Chad

回答

2

我想你可以通過具有Investment類保持一個大大的簡化問題(最好是smart)指向基類的Type。在這個例子中,我使用了一個在Investment析構函數中被刪除的原始指針,但是如果你想從Investment去耦這個類型的生命週期,你應該使用std::unique_ptrboost::scoped_ptr或者std::shared_ptr

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_; } 
}; 
+0

我不能修改我的代碼,這樣..有很多接口..我只需要知道(以及如何解決)爲什麼我電話後.. GETNEXT = \失去了指針的值 – thiagoh

1

只是一個快速瀏覽一下代碼讓我懷疑...是使用類型(即UpgradeTypeTechTypeUnitType)指針?它看起來並不像這樣,因爲您正在使用地址 - 運算符來返回getItem中的指針。

如果他們不指針,你不能把它們比作NULL,非指針是從未NULL。這意味着getItem始終返回指向unitType變量的指針。

我建議你做一個重新設計,如在juanchopanza的答案中建議的那樣。

0

由於您無法按建議重構,因此您應該根據您在init()函數中分配的type成員來檢查需要返回的類型。我認爲這會工作,但在那裏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在其答案中建議的適當的多態類級別。