22

私はC ++に比較的慣れていないため、このことに対する答えをよく探しましたが、満足のいく答えは得られませんでした.

という構造があるとしましょうFSM。最終的に私のコードでは、 の複数のインスタンスをFSM作成できます。FSMの属性の1 つはint X静的ではありません。 のすべてのインスタンスは、FSMに対して独自の値を持つ必要がありますX

さて、FSMの属性の1 つは、次のようsubmachineに の値を読み取る必要がある別の構造です。X

struct FSM
{
  public:
    int x;

    int getX(){return x;}

    struct submachine
    {
        void onentry() {int g = getX();};
    };
};

これにより、次のエラーが発生します。

エラー: 'FSM::getX': 非静的メンバー関数の不正な呼び出し

私の質問は、submachineのメンバーなFSMので、のすべての属性のローカルインスタンスにアクセスできるべきではないFSMですか? そうでない場合、 のインスタンスを作成するときに、FSMそのすべてのメンバーのインスタンスを作成することになるのではないでしょうsubmachineか? もしそうなら、なぜ必要なオブジェクトを作成するonentry()必要があるのでしょうか?

私はコンパイラが正しいと仮定しているので、これを機能させる方法があるかどうかも知りたいです.

注: 残念ながら、内部構造 ( submachine) のインスタンスは、イベントが呼び出されたときにインスタンス化されるため、タイプを定義することしかできず、 でそれらのオブジェクトをインスタンス化することはできませんFSM

4

4 に答える 4

40

私の質問は、サブマシンは FSM のメンバーであるため、FSM のすべての属性のローカル インスタンスにアクセスできるはずですよね?

いいえ。Java とは異なり、内部クラス オブジェクトは外部オブジェクトへの暗黙的な参照を持ちません。

そのすべてのメンバー、つまりサブマシンのインスタンスを作成するのではないでしょうか?

submachineメンバー変数ではなくtypeです。メンバー変数が必要な場合は、次のようにする必要があります。

struct FSM {
    struct submachine {
        ...
    };

    submachine sm;  // Member variable of type submchine
};

親オブジェクトを「見たいsm」場合は、明示的に渡す必要があります。

struct FSM {
    struct submachine {
        FSM &parent;  // Reference to parent
        submachine(FSM &f) : parent(f) {}  // Initialise reference in constructor
    };

    submachine sm;

    FSM() : sm(*this) {}  // Pass reference to ourself when initialising sm
};

submachineメンバー変数ではないのインスタンスにも同じ原則が適用されることに注意してください。インスタンスにアクセスできるようにする場合は、FSMインスタンスへの参照を渡す必要があります。

参照ではなくポインターを使用できることにも注意してください。実際、多くの場合、ポインターはより大きな柔軟性を提供します。

于 2012-07-10T00:29:37.677 に答える
2

宣言はtypestruct submachineのみを定義することに注意してください。その型のクラスに実際にフィールドを作成するわけではありません。

次のいずれかが必要です。

struct submachine mysub; // creates a field after the class is defined

また

struct submachine
{
  . . .
} mysub; // creates the field "mysub" also, as the structure is being defined

これによりmysubフィールドが作成され、アクセスするのと同じ方法でフィールドにアクセスできますx

の定義には、特定の値にアクセスすると言うことができるように、特定のフィールド (たとえば、ポインター フィールド、およびおそらくそれを初期化するコンストラクター)submachineを含める必要があります。FSMFSM*submachine(FSM* fsm): fsm_(fsm) {}fsm_->getX()X

于 2012-07-10T00:31:13.580 に答える
1

私はあなたが何をしたいのかを推測しているだけですが、私の推測が正しければ、次のようなことを考えているかもしれません.

struct FSM_Base {
    int x;

    struct submachine1;
    struct submachine2;

    FSM_Base () : x(0) {}
    virtual ~FSM_Base () {}
};

struct FSM_Base::submachine1 : virtual public FSM_Base {
    void oneentry () { int g = x; }
};

struct FSM_Base::submachine2 : virtual public FSM_Base {
    void oneentry () { int g = x; }
};

struct FSM : public FSM_Base::submachine1,
             public FSM_Base::submachine2 {
    FSM_Base::submachine1 * sub1 () { return this; }
    FSM_Base::submachine2 * sub2 () { return this; }
};
于 2012-07-10T00:50:36.597 に答える