此矢量实现的可维护性问题
Maintainability issue with this vector implementation
我有一个关于解决问题的 right/wrong(设计)方法的问题。首先我澄清情况,然后我的解决方案,最后我的解决方案的问题。我正在用 C++ 实现它。
情况:
- 类型y的class需要保存和处理特定类型x的信息集合。
- 此类型的每个实例仅与特定对象相关。
- 一个对象应该能够做 3 件事:查找与其相关的实例信息、删除实例和添加新实例。
我执行了以下操作:
- 所有信息都保存在向量 1 中。
- 其他对象具有向量中元素的索引以找到正确的实例。
但是,如果我删除一个元素怎么办?索引应该仍然有效,所以我这样做了:
- 另一个向量 2 保持并行,它包含布尔值,如果索引可用于新实例则为真,如果索引被采用则为假。我没有删除向量 1 中的实例,而是将向量 2 设置为 true。现在,如果添加了一个新实例,它将被添加到第一个可用位置(或后面)。这样就不会删除任何元素,但每次添加实例时向量都不会增长。
此解决方案的问题是:
该系统的正确行为完全取决于每个具有索引的对象。如果一个人处理他们的索引,就会出现错误问题,并且很难跟踪索引在哪里处理不当。
例如:对象 A 释放它的实例(通知 class y)但不删除索引,并且它继续对元素应用操作,而该索引现在已分配给另一个对象并且持有不同的实例!
所以我正在寻找更可靠的解决方案,可能是更好的数据结构。谢谢。
编辑:我认为描述最有帮助,但这里是 class 中保存数据的代码。
这些是向量。
std::vector<bool> availability;
std::vector<X> data;
这是方法
Y::Y() : data(1, X), availability(1, false) {
}
int Y::createNewInstance() {
if(data.size() > 1) {
bool indexFound = false;
std::vector<X>::size_type chosenIndex;
for(std::vector<X>::size_type i = 1; i < availability.size(); ++i) {
//if true, the index is not taken, so use it!
if (availability.at(i) == true) {
chosenIndex = i;
availability.at(chosenIndex) = false;
indexFound = true;
break;
}
}
if (indexFound) {
data.at(chosenIndex) = X;
return chosenIndex;
} else {
data.push_back(X);
availability.push_back(false);
return availability.size() - 1;
}
} else {
startTimes.push_back(X);
availability.push_back(false);
return availability.size() - 1;
}
}
X Y::getDataElement(int index, bool finish) {
if (data.size() > index && index != 0) {
//if finish is true, make element available for other users
if(finish) {
availability.at(index) = true;
}
return data.at(index);
}
}
如何使用 std::map 作为您的容器,其中键将是您的索引。在删除元素时更改索引不会有问题。您将需要编写一个类似 findFreeIndex 的函数来管理空闲索引。如果你不需要在 "free" space 中添加元素,你甚至不需要这个。您可以简单地总是在最大索引加一中添加新元素。
这个解决方案有轻微的性能损失,因为访问 map 比访问 vector 慢一点,但通常这不是问题。
我有一个关于解决问题的 right/wrong(设计)方法的问题。首先我澄清情况,然后我的解决方案,最后我的解决方案的问题。我正在用 C++ 实现它。
情况:
- 类型y的class需要保存和处理特定类型x的信息集合。
- 此类型的每个实例仅与特定对象相关。
- 一个对象应该能够做 3 件事:查找与其相关的实例信息、删除实例和添加新实例。
我执行了以下操作:
- 所有信息都保存在向量 1 中。
- 其他对象具有向量中元素的索引以找到正确的实例。
但是,如果我删除一个元素怎么办?索引应该仍然有效,所以我这样做了: - 另一个向量 2 保持并行,它包含布尔值,如果索引可用于新实例则为真,如果索引被采用则为假。我没有删除向量 1 中的实例,而是将向量 2 设置为 true。现在,如果添加了一个新实例,它将被添加到第一个可用位置(或后面)。这样就不会删除任何元素,但每次添加实例时向量都不会增长。
此解决方案的问题是: 该系统的正确行为完全取决于每个具有索引的对象。如果一个人处理他们的索引,就会出现错误问题,并且很难跟踪索引在哪里处理不当。
例如:对象 A 释放它的实例(通知 class y)但不删除索引,并且它继续对元素应用操作,而该索引现在已分配给另一个对象并且持有不同的实例!
所以我正在寻找更可靠的解决方案,可能是更好的数据结构。谢谢。
编辑:我认为描述最有帮助,但这里是 class 中保存数据的代码。
这些是向量。
std::vector<bool> availability;
std::vector<X> data;
这是方法
Y::Y() : data(1, X), availability(1, false) {
}
int Y::createNewInstance() {
if(data.size() > 1) {
bool indexFound = false;
std::vector<X>::size_type chosenIndex;
for(std::vector<X>::size_type i = 1; i < availability.size(); ++i) {
//if true, the index is not taken, so use it!
if (availability.at(i) == true) {
chosenIndex = i;
availability.at(chosenIndex) = false;
indexFound = true;
break;
}
}
if (indexFound) {
data.at(chosenIndex) = X;
return chosenIndex;
} else {
data.push_back(X);
availability.push_back(false);
return availability.size() - 1;
}
} else {
startTimes.push_back(X);
availability.push_back(false);
return availability.size() - 1;
}
}
X Y::getDataElement(int index, bool finish) {
if (data.size() > index && index != 0) {
//if finish is true, make element available for other users
if(finish) {
availability.at(index) = true;
}
return data.at(index);
}
}
如何使用 std::map 作为您的容器,其中键将是您的索引。在删除元素时更改索引不会有问题。您将需要编写一个类似 findFreeIndex 的函数来管理空闲索引。如果你不需要在 "free" space 中添加元素,你甚至不需要这个。您可以简单地总是在最大索引加一中添加新元素。
这个解决方案有轻微的性能损失,因为访问 map 比访问 vector 慢一点,但通常这不是问题。