问题描述
template <typename K,typename V>
class Entry {
public:
Entry(K const &key,V const &val,size_t const hash_val) :
key(key),val(val),hash_val(hash_val),empty(false){
}
K getKey() const {
return key;
}
V getValue() const {
return val;
}
size_t getHash() const {
return hash_val;
}
bool isEmpty() const{
return empty;
}
private:
// key-value pair
K key;
V val;
// Store hash for reallocation
size_t hash_val;
// Store empty state
bool empty;
};
然后我创建一个对象数组
Entry<K,V>** entries = new Entry<K,V> *[100];
如果我调用 entries[0]->isEmpty()
,我会遇到分段错误。这对我来说很有意义,因为我实际上还没有在内存中实例化一个新对象。但是,我希望能够检查数组中的插槽是否实际指向有效对象。目前,我一直将每个指针设置为 nullptr
,以便稍后检查是否相等,但我想知道是否有更好的方法。
解决方法
你想要optional
。它总是要么是一个有效的对象,要么处于“空”状态。
#include <cstdio>
#include <optional>
#include <vector>
struct Foo {
int bar;
};
int main() {
std::vector<std::optional<Foo>> vfoo{
Foo{1},std::nullopt,Foo{2},Foo{3},};
for (auto const& foo : vfoo) {
if (!foo)
std::puts("Not Initialized");
else
std::printf("Foo{%d}\n",foo->bar);
}
}
,
无法检查指针是否已初始化,因为从未初始化的指针读取是未定义的行为:
int* p;
if (p == something) ... // undefined behavior
您可以使用 nullptr
初始化指针并检查:
int* p = nullptr;
if (p == nullptr) ...
但是,您正在初始化指针。
对于 Entry<K,V>*
的动态数组,您可以使用 std::vector<Entry<K,V>*>
。可以类似于具有空槽的数组使用的容器是 std::unordered_map
:
std::unordered_map<size_t,Entry<K,V>*> map;
Entry<K,V>* ptr = get_pointer_from_somewhere();
size_t index = 42;
if ( map.find(index) == map.end() ) {
// pointer was not initialized (actually pointer is not yet in the map)
map.insert( { index,ptr }); // now it is
}
实际上,仅 insert
就可以告诉您键为 index
的元素之前是否存在于地图中。