C++ Equivalent of Java Map<String, Object>
C++ Equivalent of Java Map<String, Object>
在Java中,你可以创建一个Map,将String映射到可以显式强制转换为其他类的泛型对象类型。有什么好方法可以在C++中模仿此功能吗?
在 C++17 中,您可以使用std::map<std::string,>。
作为一种非常强的类型语言,C++没有"泛型对象类型"。它肯定有关联容器:std::map
(二叉树的味道(和std::unordered_map
(哈希表的味道(。哪个更好取决于用例,并且通常无法在不进行分析的情况下做出决定。
我能想到的最接近通用对象的是可能放在这张地图中的所有对象的共同祖先。这里的想法是创建一个具有动态多态性的类层次结构,并将映射中的对象存储为强制转换为该公共祖先的指针。 理想的设计将使这些对象转换回其派生类变得不必要。如果需要这样的转换,则必须使用dynamic_cast
(并可能检查它是否成功(。
必须存储指向地图中对象的指针,而不是对象本身。否则,在尝试插入到映射中的对象中,只会存储共同的祖先部分,并且多态性将丢失。还需要确定地图是否拥有对象(此处没有垃圾回收(。如果没有,简单的指针可能会起作用。如果地图拥有这些对象,我建议将它们包装在"唯一指针"(std::unique_ptr
(中。 总结:
#include <unordered_map>
#include <string>
#include <memory> // std::unique_ptr<>, std::make_unique()
#include <iostream>
class NotSoGenericClass {
public:
virtual ~NotSoGenericClass() = default;
virtual std::string name() const
{ return "NotTooGenericClass()"; }
};
class EvenLessGenericClass: public NotSoGenericClass {
int fValue = 0;
public:
EvenLessGenericClass(int value): fValue(value) {}
virtual std::string name() const override
{ return "EvenLessGenericClass(" + std::to_string(fValue) + ")"; }
int value() const { return fValue; }
};
int main() {
//
// map holding (and owning) "not so generic objects"
//
std::unordered_map<std::string, std::unique_ptr<NotSoGenericClass>> allObjects;
//
// populate it
//
allObjects["any"] = std::make_unique<NotSoGenericClass>();
allObjects["six"] = std::make_unique<EvenLessGenericClass>(6);
allObjects["one"] = std::make_unique<EvenLessGenericClass>(1);
std::cout << "Object 'six' says: " << allObjects["six"]->name() << std::endl;
std::cout << "Now dumping all " << allObjects.size() << " objects:";
for (auto const& keyAndObject: allObjects) {
auto const& key = keyAndObject.first;
auto const* object = keyAndObject.second.get();
//
// base class interface is always available:
//
std::cout << "n[" << key << "] " << object->name();
//
// object-specific one requires a cast:
//
auto const* lessGen = dynamic_cast<EvenLessGenericClass const*>(object);
if (lessGen) std::cout << " (value is " << lessGen->value() << ")";
} // for
std::cout << std::endl;
return 0;
} // main()
在我的平台上,此代码(使用 C++14(发出:
[one] EvenLessGenericClass(1) (value is 1)
[six] EvenLessGenericClass(6) (value is 6)
[any] NotTooGenericClass()
(也说明了地图名称中"无序"的含义(。 此示例是使用g++ -Wall -pedantic -std=c++14 -o test.exe test.cpp
(GCC 6.4.0( 编译的。
相关文章:
- cppcheck在const std::string[]上引发警告
- 将std::string传递给WriteConsole API
- 为std::string的某个索引赋值
- std中有类似find_last_of的函数,而string中没有
- 使用 std::string () const 函数启动线程或未来
- 使用char类型将decimal转换为string,将string转换为decimal
- 迭代和比较映射<字符串、矢量<string>> c++ 中的值
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 将向量解析<string>为字符串
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 当覆盖存在时调用基本虚拟"binded to object"函数
- 如何更改大小(std::string)
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- std::string 的对象真的可以移动吗?
- 与'operator='不匹配(操作数类型'String'且"void")
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- C++ Equivalent of Java Map<String, Object>
- 构造函数 c++ Object obj = Object( "string" , 22);正在创建临时对象?
- 保存在String Object中的HugeInteger对象的位数