我一直在阅读和尝试使用标准库的智能指针`unique_ptr`和`shared_ptr`,虽然它们显然是替代原始指针的好选择,但当实现数据结构时,我不确定它们的使用方法。
为了进行实验,我编写了一个使用`shared_ptr`的哈希表示例,根据Meyer's Effective Modern C ++,其大约是`unique_ptr`的两倍大小。因此,出于这个原因,我想使用`unique_ptr`,但由于在添加函数中所执行的更新和复制操作,我有些困惑。
有人对此问题有什么建议吗?是否应该继续使用原始指针来编写数据结构?
为了进行实验,我编写了一个使用`shared_ptr`的哈希表示例,根据Meyer's Effective Modern C ++,其大约是`unique_ptr`的两倍大小。因此,出于这个原因,我想使用`unique_ptr`,但由于在添加函数中所执行的更新和复制操作,我有些困惑。
有人对此问题有什么建议吗?是否应该继续使用原始指针来编写数据结构?
#pragma once
#include "core.h"
const int TABLE_SIZE = 256;
template<typename K>
class HashKey {
public:
unsigned long operator()(const K& p_key) const {
return (p_key) % TABLE_SIZE;
}
};
template<typename K, typename T>
class HashNode {
public:
K m_key;
T m_value;
std::shared_ptr<HashNode> next = nullptr;
};
template<typename K, typename T, typename F = HashKey<K>>
class HashMap {
public:
std::array< std::shared_ptr< HashNode<K, T> >, 128 > m_table;
F m_hash_function;
int m_elem_count{ 0 };
void Add(K p_key, T p_value);
};
template<typename K, typename T, typename F = HashKey<K>>
void HashMap<K, T, F>::Add(K p_key, T p_value)
{
unsigned long key = m_hash_function(p_key);
std::shared_ptr<HashNode<K, T>> new_node = std::make_shared<HashNode<K, T>>();
new_node->m_key = p_key;
new_node->m_value = p_value;
if (m_table[key] == nullptr) {
/* only item in the bucket */
m_table[key] = std::move(new_node);
m_elem_count++;
}
else {
/* check if item exists so it is replaced */
std::shared_ptr< HashNode<K, T> > current = m_table[key];
std::shared_ptr< HashNode<K, T> > previous = m_table[key];
while (current != nullptr && p_key != current->m_key ) {
previous = current;
current = current->next;
}
if (current == nullptr) {
previous->next = new_node;
//current = new_node;
m_elem_count++;
}
else {
current->m_value = p_value;
}
}
}
void TestHashMap() {
HashMap<int, std::string> hash_map;
hash_map.Add(1, "one");
hash_map.Add(2, "does");
hash_map.Add(3, "not");
hash_map.Add(50, "simply");
hash_map.Add(11, "waltz");
hash_map.Add(11, "into");
hash_map.Add(191, "mordor");
std::cout << hash_map.m_elem_count << std::endl;
}
std::shared_ptr
),还是一次只能有一个所有者(std::unique_ptr
)取决于具体情况。 - Some programmer dudestd::array
。 为什么不用std::vector<HashNode<K, T>>
来实现哈希映射呢?通常,这个问题让我有些困惑:你应该做的大部分工作是编写数据结构(以及它们的算法)。因此,你当然会为数据结构使用智能指针,而不是笨重的指针 - 否则你还会用智能指针来做什么?没有其他用途了。 - Konrad Rudolphstd::unique_ptr
目前无法传递到寄存器内的函数中,而原始指针可以)。但总的来说,很难做出这样的断言,因为编译器中的优化器变得越来越好,并且在手动实现中所做的许多假设会因平台而异。特别是,我甚至不确定你所说的“放弃概念所有权后使用...”是什么意思。那听起来像是未定义行为。 - Konrad Rudolphstd::unique_ptr
则不能(假设在代码的那部分不需要异常安全)。 - JSFunique_ptr
来管理所有权(转移),并使用原始指针来维护对同一对象的传递性、非拥有引用。 - Konrad Rudolph