AbstractFieldCollection是hardwareMissingAlarm等的基类。 hardwareMissingAlarm属于另一个模板类。
alarmFieldCollection.push_back((AbstractAlarmField Device::*) &Device::hardwareMissingAlarm);
alarmFieldCollection.push_back((AbstractAlarmField Device::*) &Device::hardwareErrorAlarm);
alarmFieldCollection.push_back((AbstractAlarmField Device::*) &Device::badConfigAlarm);``
然后在另一个函数中我正在读这样的矢量:
for(int32_t i=0; i<alarmFieldCollection.size(); i++)
{
AbstractAlarmField Device::* pAF = alarmFieldCollection[i];
std::cout << "isRaised: "<< pDev << std::endl;
if ((pDev->*pAF).isRaised(pContext))
{
.....
}
}
和pDev
是设备对象,但pDev->*pAF
返回NULL
。事实上,当我打印&Device::hardwareErrorAlarm
,&Device::hardwareMissingAlarm
时,结果是1.我不知道我做错了什么。
isRaised
是属于class AbstractAlarmField
的方法。
提前致谢。
答案 0 :(得分:2)
您几乎没有提供任何代码,但似乎您按值存储抽象对象,而不是通过引用或指针存储。这可能导致对象切片和任何类型的内存问题。请尝试使用AbstractAlarmField&
作为Device
字段的类型。
答案 1 :(得分:0)
将成员指针X C::*
转换为Y C::*
没用。标准允许它作为reinterpret_cast
或C样式的强制转换,但具有完全未指定的结果(除非您转换回原始类型)。您最好使用虚拟仿函数安全地获取AbstractAlarmField
子对象:
#include <type_traits>
#include <memory>
struct AlarmGetter {
public:
virtual ~AlarmGetter();
virtual AbstractAlarmField& get(Device& dev) const = 0;
};
template <typename T>
struct AlarmMemberPtr
: public AlarmGetter {
static_assert(std::is_base_of<AbstractAlarmField, T>::value,
"Member type is not an AbstractAlarmField");
public:
explicit AlarmMemberPtr(T Device::*member)
: m_member( member ) {}
virtual AbstractAlarmField& get(Device& dev) const {
return dev.*m_member;
}
private:
T Device::*m_member;
};
template <typename T>
std::unique_ptr<AlarmGetter> make_alarm_getter(T Device::*member) {
std::unique_ptr<AlarmGetter> ptr(new AlarmMemberPtr<T>(member));
return ptr;
}
// To populate:
std::vector<std::unique_ptr<AlarmGetter>> alarmFieldCollection;
alarmFieldCollection.push_back(make_alarm_getter(&Device::hardwareMissingAlarm));
alarmFieldCollection.push_back(make_alarm_getter(&Device::hardwareErrorAlarm));
alarmFieldCollection.push_back(make_alarm_getter(&Device::badConfigAlarm));
// To use:
if (alarmFieldCollection[i]->get(*pDev).isRaised(pContext))
如果它可能有用,您也可以轻松添加重载
virtual const AbstractAlarmField& get(const Device& dev) const;