3

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是 Device 对象,但pDev->*pAF返回NULL. 事实上,当我打印时&Device::hardwareErrorAlarm&Device::hardwareMissingAlarm 结果是 1。我不知道我做错了什么。

isRaised是属于的方法class AbstractAlarmField

提前致谢。

4

2 回答 2

2

您几乎没有提供任何代码,但您似乎是按值存储抽象对象,而不是按引用或指针。这可能会导致对象切片和任何类型的内存问题。尝试改用AbstractAlarmField&作为Device字段的类型。

于 2013-01-14T13:59:32.693 回答
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;
于 2013-01-14T15:56:11.270 回答