如何编写可接受任意类对象的成员函数及Hash Map实现类?
解答你的两个C++问题
问题1:如何编写能接受任意类型类对象的成员函数?
要实现能处理任意类对象的成员函数,C++里最常用也最优雅的方式就是模板成员函数——它能让函数适配任意类型,不用为每个类写重复的重载代码,完美解决泛型处理的需求。
举个直观的例子,比如我们写一个工具类,里面有个成员函数用来打印任意对象的大小:
#include <iostream> class ObjectHandler { public: // 模板成员函数:T可以是任意类型(自定义类、内置类型都能行) template <typename T> void logObjectSize(const T& obj) const { std::cout << "这个对象的大小是:" << sizeof(obj) << " 字节" << std::endl; } };
使用起来非常灵活,不管是你定义的A、B类,还是int、string这类内置/标准库类型,都能直接传进去:
class A { public: int a; }; class B { public: char b; }; int main() { ObjectHandler handler; A a_obj; B b_obj; handler.logObjectSize(a_obj); // 输出:这个对象的大小是:4 字节(假设int为4字节) handler.logObjectSize(b_obj); // 输出:这个对象的大小是:1 字节 handler.logObjectSize(std::string("hello")); // 也能处理标准库类型 return 0; }
小提示:模板函数的声明和定义最好放在头文件里(如果要分开写需要特殊处理,新手直接放头文件最不容易踩坑);如果需要对某几个特定类型做特殊逻辑,可以用模板特化来单独实现。
问题2:实现支持任意类对象作为键、基于对象大小计算哈希的Hash Map类?
结合你的需求,我们可以用模板类+自定义哈希函数来实现这个Hash Map。核心思路是:用模板让Hash Map支持任意键类型,同时自定义哈希规则,基于对象的大小生成哈希值;另外,自定义类作为键时需要支持相等比较,这样Hash Map才能判断键是否重复。
完整实现示例
#include <unordered_map> #include <string> #include <iostream> // 第一步:自定义哈希函数——基于对象的大小计算哈希值 template <typename T> struct SizeHash { size_t operator()(const T& obj) const { // 直接用sizeof作为哈希值,你也可以加一些散列逻辑减少冲突 size_t hash = sizeof(obj); // 可选:简单的散列优化,降低同大小类型的哈希冲突 hash ^= hash << 13; hash ^= hash >> 17; hash ^= hash << 5; return hash; } }; // 第二步:实现我们的Hash Map模板类 template <typename KeyType, typename ValueType> class SizeBasedHashMap { private: // 底层用标准库的unordered_map,指定我们的自定义哈希函数 std::unordered_map<KeyType, ValueType, SizeHash<KeyType>> internal_map; public: // 插入键值对 void put(const KeyType& key, const ValueType& value) { internal_map[key] = value; } // 根据键查找值,返回是否找到,找到的话把值存在out_value里 bool get(const KeyType& key, ValueType& out_value) const { auto iter = internal_map.find(key); if (iter != internal_map.end()) { out_value = iter->second; return true; } return false; } // 获取当前存储的键值对数量 size_t count() const { return internal_map.size(); } }; // 你的自定义类A和B,需要重载==运算符用于键的相等判断 class A { public: int a; // 必须重载==,否则Hash Map无法判断两个A对象是否相等 bool operator==(const A& other) const { return this->a == other.a; } }; class B { public: char b; bool operator==(const B& other) const { return this->b == other.b; } }; // 测试代码 int main() { // 测试用A类作为键的Hash Map SizeBasedHashMap<A, std::string> a_hash_map; A obj_a1{10}, obj_a2{20}; a_hash_map.put(obj_a1, "对应A对象a=10的值"); a_hash_map.put(obj_a2, "对应A对象a=20的值"); std::string a_result; if (a_hash_map.get(obj_a1, a_result)) { std::cout << "找到A对象的值:" << a_result << std::endl; } // 测试用B类作为键的Hash Map SizeBasedHashMap<B, int> b_hash_map; B obj_b1{'x'}, obj_b2{'y'}; b_hash_map.put(obj_b1, 100); b_hash_map.put(obj_b2, 200); int b_result; if (b_hash_map.get(obj_b2, b_result)) { std::cout << "找到B对象的值:" << b_result << std::endl; } return 0; }
关键说明
- 自定义哈希函数:
SizeHash结构体重载了operator(),接收任意类型的对象,返回基于其大小的哈希值。如果觉得直接用sizeof冲突太多(比如所有4字节的类型哈希值相同),可以加上散列优化逻辑。 - 相等比较:自定义类作为Hash Map的键时,必须重载
operator==,因为标准库的哈希容器需要判断两个键是否相等来处理冲突和查找。 - 模板类的灵活性:
SizeBasedHashMap是模板类,支持任意键类型和值类型,你可以根据需求换成int、string或者其他自定义类。
内容的提问来源于stack exchange,提问作者Tuhin Panda
相关产品推荐
相关产品推荐

