在 std::unordered_map 中存储指向不同类型 类 的指针
store pointers to different types of classes in an std::unordered_map
我有需要进行操作的设备。我有一个基地 class BASE
和一个 child class TYPE1
。
每个设备都是 TYPE1
的实例。这些由另一个 class 实例化,具体取决于 xml 配置文件中存在的内容。
class BASE {
public:
BASE();
virtual ~BASE();
};
class TYPE1 : public BASE {
public:
TYPE1();
};
现在我将指向这些实例的指针存储在一个 std::unordered_map
中,定义为:
std::unordered_map <std::string, TYPE1 *> myDevices;
其中 std::string
是配置文件中也使用的标识键。
如果我需要,std::unordered_map
可以让我快速直接访问 object,如果我使用
遍历它,我可以方便地在所有设备上执行相同的操作
for ( auto& elem : myDevices ) {
//do stuff
}
设备的顺序并不重要,因此 std::unordered_map
。
我在整个代码中广泛使用它。
现在我需要一个 TYPE2
,它也是 BASE
的 child,但类型不同。
TYPE1
和 TYPE2
都实现了相同的方法 - 它们的功能不同 - 但产生相同的结果
我的问题:
如何修改
std::unordered_map <std::string, TYPE1 *> myDevices;
所以它接受所有类型的 classes 像
std::unordered_map <std::string, acceptAnyTypeOfClass *> myDevices;
我受阻了,虽然我认为我可以绕过它,但它很快就会变得丑陋,我真的很想以一种干净的方式来做。我问的是可能的吗?如果可以,请问如何?
想到的第一个选项是使用指向基 class 的指针,因为 TYPE1
和 TYPE2
对象都是 BASE
对象:
std::unordered_map <std::string, BASE*> myDevices;
问题是如何区分 TYPE1*
指针和 TYPE2*
指针?
由于 TYPE1
和 TYPE2
都实现了相同的方法,最好的方法可能是使用多态性,使用虚函数:
class BASE {
public:
BASE();
virtual void doSomething()=0;
virtual ~BASE();
};
class TYPE1 : public BASE {
public:
TYPE1();
void doSometing() override { /* the code for TYPE 1 devices*/ }
};
class TYPE2 : public BASE {
public:
TYPE2();
void doSometing() override { /* the code for TYPE 2 devices*/ }
};
然后您可以调用函数而不必担心基础对象的真实类型:
std::unordered_map <std::string, BASE*> myDevices;
...
for (auto& elem : myDevices ) {
elem->doSomething();
}
P.S: 如果动态创建设备对象,可以考虑在映射中使用唯一或共享指针,以避免内存泄漏。
我有需要进行操作的设备。我有一个基地 class BASE
和一个 child class TYPE1
。
每个设备都是 TYPE1
的实例。这些由另一个 class 实例化,具体取决于 xml 配置文件中存在的内容。
class BASE {
public:
BASE();
virtual ~BASE();
};
class TYPE1 : public BASE {
public:
TYPE1();
};
现在我将指向这些实例的指针存储在一个 std::unordered_map
中,定义为:
std::unordered_map <std::string, TYPE1 *> myDevices;
其中 std::string
是配置文件中也使用的标识键。
如果我需要,std::unordered_map
可以让我快速直接访问 object,如果我使用
for ( auto& elem : myDevices ) {
//do stuff
}
设备的顺序并不重要,因此 std::unordered_map
。
我在整个代码中广泛使用它。
现在我需要一个 TYPE2
,它也是 BASE
的 child,但类型不同。
TYPE1
和 TYPE2
都实现了相同的方法 - 它们的功能不同 - 但产生相同的结果
我的问题:
如何修改
std::unordered_map <std::string, TYPE1 *> myDevices;
所以它接受所有类型的 classes 像
std::unordered_map <std::string, acceptAnyTypeOfClass *> myDevices;
我受阻了,虽然我认为我可以绕过它,但它很快就会变得丑陋,我真的很想以一种干净的方式来做。我问的是可能的吗?如果可以,请问如何?
想到的第一个选项是使用指向基 class 的指针,因为 TYPE1
和 TYPE2
对象都是 BASE
对象:
std::unordered_map <std::string, BASE*> myDevices;
问题是如何区分 TYPE1*
指针和 TYPE2*
指针?
由于 TYPE1
和 TYPE2
都实现了相同的方法,最好的方法可能是使用多态性,使用虚函数:
class BASE {
public:
BASE();
virtual void doSomething()=0;
virtual ~BASE();
};
class TYPE1 : public BASE {
public:
TYPE1();
void doSometing() override { /* the code for TYPE 1 devices*/ }
};
class TYPE2 : public BASE {
public:
TYPE2();
void doSometing() override { /* the code for TYPE 2 devices*/ }
};
然后您可以调用函数而不必担心基础对象的真实类型:
std::unordered_map <std::string, BASE*> myDevices;
...
for (auto& elem : myDevices ) {
elem->doSomething();
}
P.S: 如果动态创建设备对象,可以考虑在映射中使用唯一或共享指针,以避免内存泄漏。