我得到了一个如下所述的课程
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;
}
答案 0 :(得分:2)
我认为你可以通过Investment
类保存一个指向Type
基类的指针(最好是smart)来大大简化问题。在此示例中,我使用了一个原始指针,该指针在Investment
析构函数中被删除,但如果您需要,您应该使用std::unique_ptr,boost::scoped_ptr或std::shared_ptr将类型的生命周期与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_; }
};
答案 1 :(得分:1)
快速查看代码会让我产生怀疑......使用的类型(即UpgradeType
,TechType
和UnitType
)指针是什么?它看起来不像那样,因为你使用address-of运算符在getItem
中返回它们的指针。
如果它们不是指针,则无法将它们与NULL
进行比较,因为非指针从不 NULL
。这意味着getItem
将始终返回指向unitType
变量的指针。
我建议你重新设计,就像juanchopanza在答案中所建议的那样。
答案 2 :(得分: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在其答案中所建议的那样。