Вопрос по structure, c++ – Внутренний класс, обращающийся к внешнему классу [duplicate]

19

This question already has an answer here:

Inner Class access to Outer Class members 5 answers

Я относительно новичок в C ++, и я долго искал ответ на этот вопрос, но я так и не получил удовлетворительного ответа.

Допустим, у меня есть структура под названиемFSM, В конечном итоге в моем коде несколько экземпляровFSM может быть создан. Один изFSMатрибутыint X который не является статичным, каждый случайFSM должен иметь свою ценность дляX.

Теперь один изFSMатрибуты - это другая структураsubmachine который должен прочитать значениеX как это:

struct FSM
{
  public:
    int x;

    int getX(){return x;}

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

Это дает следующую ошибку:

Error: 'FSM::getX' : illegal call of non-static member function

Мой вопросsubmachine является членомFSMпоэтому он не должен иметь доступа к локальным экземплярам всех атрибутовFSM? И если нет, то когда мы создаем экземплярFSMЕсли бы мы не создавали экземпляр всех его членов, т.е.submachine? И если так, то зачем нам создавать объект, которыйonentry() потребности?

Я предполагаю, что компилятор корректен, поэтому я также хотел бы знать, есть ли способ заставить эту работу работать.

ПРИМЕЧАНИЕ: К сожалению, экземпляры внутренних структур (submachine) создаются, когда вызывается событие, и поэтому я могу только определять тип, а не создавать объекты для них вFSM.

Ваш Ответ

4   ответа
2

Обратите внимание, что объявлениеstruct submachine определяет толькоtype; фактически он не создает поле в классе этого типа.

Вам понадобится одно из следующих:

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 необходимо включить конкретныйFSM (например, поле указателяFSM*и, вероятно, конструктор, какsubmachine(FSM* fsm): fsm_(fsm) {} инициализировать его) так что вы можете сказатьfsm_->getX() чтобы получить доступ к определенномуX значение.

К сожалению, экземпляры внутренних структур объявлены во время выполнения (события), и поэтому я могу только определять тип, а не создавать экземпляры объектов для них. Kam
Вы все еще не можете сделатьint g = getX(); безFSM объект. Как это отвечает на вопрос?
34

my question is, submachine is a member of FSM, so it should have access to local instances of all the attributes of FSM, no?

Нет. В отличие от Java, объекты внутреннего класса не имеют неявной ссылки на внешний объект.

wouldn't we be creating an intance of all its members i.e. submachine?

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 Например, вам нужно передать ссылку на него.

Обратите внимание, что вы можете использовать указатель, а не ссылку. Фактически, указатель предлагает большую гибкость во многих случаях.

Downvoter: хочешь поделиться?
@Kam: Вам нужно будет создать экземплярsubmachine somewhere хоть? Как это будет сделано? Как это будет привязано к конкретномуFSM объект?
@Kam: Хорошо. Ну, тот же принцип применяется. Всякий раз, когда вы строитеsubmachine Например, вам нужно будет передать ему ссылку наFSM пример. (Тем не менее, я не знаком с этой библиотекой Boost, так что, возможно, в API есть кое-что, что делает это сложным.)
Я нашел примечание в документации Boost.MSM о конструкции конечного автомата (и автомата) - надеюсь, это имеет больше смысла для OP, чем для меня
@Kam: Я не понимаю слова, которое ты только что сказал. Вы должны сделать новый вопрос
3

учтите, что в вашем примере я могу легально написать бесплатную функцию

void foo()
{
    FSM::submachine sub;
    sub.onentry();
}

где естьno Экземпляр FSM, которыйsub может относиться к.

Либо, как говорит Оли, естьsubmachine объект хранит ссылку на своего родителяFSM объект, или, возможно, просто передать значениеx прямо вonentry (не ясно, как это вызывается).


Из быстрого взгляда наBoost.MSM документы Я нашел эту записку нане созданные по умолчанию машины.

Это довольно уродливо, я недостаточно понимаю бэкэнд, чтобы перефразировать его здесь, и буквальный код не будет иметь достаточного смысла в отдельности, чтобы его можно было вставить.

Примерный код, связанный оттуда, также показывает способ ввода в подсистему со следующей подписью:

template <class Event,class FSM> void on_entry(Event const&,FSM& );

если это точно, вы можете сохранить указатель на ваш внешний конечный автоматon_entryили извлеките значение x и запишите его в автомате.

Спасибо! Это то, что я искал, теперь я на самом деле понимаю. этот пост с постом OLI сделал это для меня. Я хотел бы принять оба ответа. Kam
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; }
};

Похожие вопросы