1

私は C++ が初めてで、メソッドのパラメーターとして任意の構造体を受け入れることができるかどうかを知りたいです。

これが事実です。hw_managerハードウェア クラス ( としましょう) とやり取りする1 つのクラス ( としましょうhw_device1) があります。現在hw_manager、 のメソッドが呼び出され、メソッドのhw_device1結果が構造体パラメータを介して返されます (参照として構造体パラメータを送信し、参照されたパラメータの値を変更します)。

C++ コードでは、次のようになります。

struct sSensorStatus {
    unsigned char sensor1;
    unsigned char sensor2;
};

bool checkSensorStatus(struct sSensorStatus &status) {
    // Change the status here
}

さて、ハードウェアが変更されたので、hw_device2まったく異なる操作を行う新しいクラスを作成する必要があります。

struct sHardwareStatus {
    unsigned char loader;
    unsigned char transport;
    unsigned char ejector;
    unsigned char mouth;
};

bool checkHardwareStatus(struct sHardwareStatus &status) {
    // Change the status here
}

コードを変更するのではなく(この層の上のコードに影響します)、インターフェイスを実装する予定です。たとえば、メソッドを持っているとしhw_managerましょう。アイデアは次のとおりです。IHardwaredoAction

bool doAction(int cmdID, ????) {
    // switch case cmdID
    // based on the cmdID, type cast the ???? into the struct
}

何を入れようかな???? あらゆる種類の構造体を受け入れるには?これを C++ で行うことはできますか?

ありがとう

編集

ハードウェアの内部には別の構造体もありますので、テンプレートを使用するのは適切ではないと思います。説明が遅くなり申し訳ありません。

4

4 に答える 4

4

単純にポリモーフィズムを使用します。すべてのデバイスの基本クラスを作成し、それへのポインタまたは参照を引数としてメソッドに渡しますdoAction

編集(elyashivの回答に対するKoushikのコメントに感謝):

実際には、メソッド doAction をすべてのデバイスの基本クラスの仮想メソッドにし、何も渡さないようにする方が良い解決策です。

于 2013-04-09T07:49:41.063 に答える
2

あなたはこれを行うことができます:

struct IHardware{virtual doAction() = 0;} 

今それを継承します

struct sHardwareStatus : public IHardware
{/*implementation with implementation for doAction()*/
    unsigned char loader;
    unsigned char transport;
     unsigned char ejector;
    unsigned char mouth;
     /*provide concrete definition for bool doAction() here*/
}

のためにも

srtuct sSensorStatus : public IHardware
{/*implementation with implementation for doAction()*/
    unsigned char sensor1;
    unsigned char sensor2;
    /*provide concrete definition for bool doAction() here*/
}

インターフェイスから新しいハードウェアを継承し、そのクラスの構造体を作成する場合。doAction()ハードウェアごとに異なると思います。

于 2013-04-09T08:09:19.870 に答える
1

呼び出す構造体と関数の数が少ない場合は、テンプレートとテンプレートの特殊化を使用できます。

template<typename T>
bool doAction(T& s)
{
    return false;
}

template<>
bool doAction(sSensorStatus& status)
{
    return checkSensorStatus(status);
}

template<>
bool doAction(sHardwareStatus& status)
{
    return checkHardwareStatus(status);
}

ご覧のとおり、フラグは実際には必要ありません。cmdIDコンパイラは、構造体の型だけを使用して、それ自体を把握します。

于 2013-04-09T07:51:06.440 に答える
1

継承を使用する必要があります。
そのようなものはうまく配置されています:

struct HardwareStatusInterface{};
struct sHardwareStatus : public HardwareStatusInterface
 {
    unsigned char loader;
    unsigned char transport;
    unsigned char ejector;
    unsigned char mouth;
};
struct sSensorStatus : publc HardwareStatusInterface
 {
    unsigned char sensor1;
    unsigned char sensor2;
};

そして機能:

bool doAction(int cmdID, HardwareStatusInterface &HI) {
    // switch case cmdID
    // based on the cmdID, type cast the ???? into the struct
}
于 2013-04-09T07:52:42.670 に答える