编辑了一段时间后,仍然有一个未处理的异常


Inventory::Inventory()
{
this->cap = 10;
this->nrOfItems = 0;
this->itemArr = new Item* [cap]();
}

Inventory::~Inventory()
{
for (size_t i = 0; i < this->nrOfItems; i++)
{
delete this->itemArr[i];
}
delete[] this->itemArr;
}
void Inventory::expand()
{
this->cap *= 2;
Item **tempArr = new Item*[this->cap]();

for (size_t i = 0; i < this->nrOfItems, i++;)
{
tempArr[i] = new Item(*this->itemArr[i]);
}
for (size_t i = 0; i < this->nrOfItems, i++;)
{
delete this->itemArr[i];
}
delete[] this->itemArr;

this->itemArr = tempArr;
this->initialize(this->nrOfItems);
}
void Inventory::initialize(const int from)
{
for (size_t i = from; i < cap, i++;)
{
this->itemArr[i] = nullptr;
}
}
void Inventory::addItem(const Item& item)
{
if (this->nrOfItems >= this->cap)
{
expand();
}
this->itemArr[this->nrOfItems++] = new Item(item);
}
void Inventory::removeItem(int index)
{
}

上面是我从Inventory.cpp中得到的代码,问题是我一直从以下行中得到一个未处理的异常:

this->itemArr[i] = nullptr;

我不知道我把代码搞砸了。下面我从库存发布。h:

class Inventory
{
private:
int cap;
int nrOfItems;
Item **itemArr;
void expand();
void initialize(const int from);
public:
Inventory();
~Inventory();
void addItem(const Item &item);
void removeItem(int index);
inline void debugPrint() const    
{
for (size_t i = 0; i < this->nrOfItems; i++)
{
std::cout << this->itemArr[i]->debugPrint() << std::endl;
}
}
};

这是itemArr应该放置的地方,但由于某种原因,它没有拉动。我是编码的新手,所以我不知道所有的技巧和窍门。

在循环i < cap, i++;中,您将首先检查i是否在边界内,然后在执行循环体之前将其增加一。因此,如果i=cap-1检查将通过,那么i将变为cap,您就越界了。而是写入(size_t i = from; i < cap;i++),以便在循环体之后执行i的增量。

A看到您的代码有几个问题:

  • Inventory::expand()中,由于您使用的是指针数组(为什么不使用对象数组?(,因此无需将现有Item对象克隆到新数组,只需按原样复制现有指针即可。您只是在扩展数组以容纳更多的指针,所以克隆会浪费开销。这不是一个致命的问题,但这是你应该意识到的。

  • Inventory::initialize()Inventory::expand()中,循环设置不正确。您在错误的位置执行i++。给定循环的定义:

    for ( <init-statement> <condition> ; <iteration_expression> )

    您正在执行i++作为<condition>的一部分,而不是<iteration_expression>。这只是由于您使用comma operator而不是;造成的打字错误,但却是一个重要的打字错误。

  • Inventory未实现复制/移动构造函数和复制移动赋值运算符,违反了3/5/0规则。

话虽如此,还是试试这个:

class Inventory
{
private:
size_t cap;
size_t nrOfItems;
Item **itemArr;
void expand();

public:
Inventory();
Inventory(const Inventory &src);
Inventory(Inventory &&src);
~Inventory();
Inventory& operator=(Inventory rhs);
void addItem(const Item &item);
void removeItem(size_t index);
inline void debugPrint() const    
{
for (size_t i = 0; i < nrOfItems; ++i)
{
std::cout << itemArr[i]->debugPrint() << std::endl;
}
}
};
Inventory::Inventory()
{
cap = 10;
nrOfItems = 0;
itemArr = new Item*[cap]();
}
Inventory::Inventory(const Inventory &src)
{
cap = src.cap;
nrOfItems = src.nrOfItems;
itemArr = new Item*[cap]();
for(size_t i = 0; i < nrOfItems; ++i)
{
itemArr[i] = new Item(*(src.itemArr[i]));
}
}
Inventory::Inventory(Inventory &&src)
{
cap = src.cap; src.cap = 0;
nrOfItems = src.nrOfItems; src.nrOfItems = 0;
itemArr = src.itemArr; src.itemArr = nullptr;
}
Inventory::~Inventory()
{
for (size_t i = 0; i < nrOfItems; ++i)
{
delete itemArr[i];
}
delete[] itemArr;
}
Inventory& Inventory::operator=(Inventory rhs)
{
Inventory temp(std::move(rhs));
std::swap(cap, temp.cap);
std::swap(nrOfItems, temp.nrOfItems);
std::swap(itemArr, temp.itemArr);
return *this;
}
void Inventory::expand()
{
size_t newCap = cap * 2;
Item **tempArr = new Item*[newCap]();
for (size_t i = 0; i < nrOfItems; ++i)
{
tempArr[i] = itemArr[i];
}
delete[] itemArr;
itemArr = tempArr;
cap = newCap;
}
void Inventory::addItem(const Item& item)
{
if (nrOfItems >= cap)
{
expand();
}
itemArr[nrOfItems] = new Item(item);
++nrOfItems;
}
void Inventory::removeItem(size_t index)
{
if (index < nrOfItems)
{
Item *item = itemArr[index];
for(size_t i = index + 1; i < nrOfItems; ++i)
{
itemArr[i-1] = itemArr[i];
}
--nrOfItems;
itemArr[nrOfItems] = nullptr;
delete item;
}
}

也就是说,你真的应该使用std::vector,让它为你处理这些细节,例如:

#include <vector>
class Inventory
{
private:
std::vector<Item> itemVec;

public:
Inventory();
void addItem(const Item &item);
void removeItem(size_t index);
inline void debugPrint() const    
{
for (Item &item : items)
{
std::cout << item.debugPrint() << std::endl;
}
}
};
Inventory::Inventory()
{
itemVec.reserve(10);
}
void Inventory::addItem(const Item& item)
{
itemVec.emplace_back(item);
}
void Inventory::removeItem(size_t index)
{
if (index < itemVec.size())
{
itemVec.erase(itemVec.begin() + index);
}
}

看看这有多简单?:(

相关内容

最新更新