我有需要进行操作的设备。我有一个基类BASE
和一个子类TYPE1
。
每个设备都是TYPE1
的实例。这些由另一个类实例化,具体取决于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
可让我快速直接访问对象,并且如果我使用
for ( auto& elem : myDevices ) {
//do stuff
}
设备的顺序并不重要,因此std::unordered_map
。
我在整个代码中广泛使用它。
现在我需要一个TYPE2
,它也是BASE
的孩子,但不同的类型。
TYPE1
和TYPE2
都实施了相同的方法 - 它们的功能不同 - 但会产生相同的结果
我的问题:
如何修改
std::unordered_map <std::string, TYPE1 *> myDevices;
所以它接受所有类型的类,如
std::unordered_map <std::string, acceptAnyTypeOfClass *> myDevices;
我被封锁了,虽然我觉得我可以绕过它会很快变得丑陋而且我真的想以干净的方式做到这一点。我问的是可能的,如果是这样,请问怎么样?
答案 0 :(得分:2)
首先想到的选项是使用指向基类的指针,因为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:如果动态创建设备对象,可以考虑在地图中使用唯一或共享指针,以避免内存泄漏。