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 に答える