内部类访问外部类 对于C++我是比较新的,我已经为这个问题寻找了很多答案,但是我从来没有得到满意的答案。

内部类访问外部类 对于C++我是比较新的,我已经为这个问题寻找了很多答案,但是我从来没有得到满意的答案。,c++,structure,C++,Structure,假设我有一个名为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();};

假设我有一个名为
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();};
    };
};
struct FSM {
    struct submachine {
        ...
    };

    submachine sm;  // Member variable of type submchine
};
这会产生以下错误:

错误:“FSM::getX”:非法调用非静态成员函数

我的问题是,
submachine
FSM
的成员,所以它不应该访问
FSM
的所有属性的本地实例吗?如果不是,当我们创建一个
FSM
的实例时,我们不是在创建一个它的所有成员的实例,即
子机
?如果是这样,那么为什么我们需要创建一个
onentry()
需要的对象呢

我假设编译器是正确的,所以我还想知道是否有办法让它工作


注意:不幸的是,内部结构(
submachine
)的实例是在调用事件时实例化的,因此我只能定义类型,而不能在
FSM
中为它们实例化对象

我的问题是,submachine是FSM的成员,所以它应该可以访问FSM所有属性的本地实例,不是吗

不。与Java不同,内部类对象没有对外部对象的隐式引用

我们不是要创建一个包含所有成员的实体,即子机器吗

submachine
是一种类型,而不是成员变量。如果需要成员变量,则必须执行以下操作:

struct FSM
{
  public:
    int x;

    int getX(){return x;}

    struct submachine
    {
        void onentry() {int g = getX();};
    };
};
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
};
请注意,相同的原则适用于非成员变量的
子机
。如果您希望他们能够访问
FSM
实例,则需要传递一个对实例的引用


还请注意,您可以使用指针而不是引用。事实上,指针在许多情况下提供了更大的灵活性。

请注意,声明
struct submachine
仅定义类型;它实际上并不在该类型的类中创建字段

您将需要以下选项之一:

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

这使
mysub
成为字段,然后您可以使用与访问
x
相同的方式访问它


submachine
的定义需要包含一个特定的
FSM
(例如,指针字段
FSM*
,可能还有一个类似
submachine(FSM*FSM)的构造函数:FSM_(FSM){}
来初始化它),这样你就可以说
FSM_->getX()
访问某个
X
值。

我只是在猜测您想做什么,但是如果我的猜测是正确的,您可能会想到下面这样的事情

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; }
};

在你的例子中,我可以合法地编写一个自由函数

void foo()
{
    FSM::submachine sub;
    sub.onentry();
}
没有
sub
可以引用的FSM实例

正如Oli所说,要么让
子机
对象存储对其父
FSM
对象的引用,要么直接将
x
的值传递到
onentry
(不清楚如何调用它)


快速看了一下,我发现这张便条就在上面

它非常难看,我对后端的理解还不够透彻,无法在这里进行解释,并且文字代码在孤立的情况下没有足够的意义,不值得粘贴

从那里链接的示例代码还显示了具有以下签名的子机器的输入方法:

template <class Event,class FSM> void on_entry(Event const&,FSM& );
输入时模板无效(事件常量和FSM&);

如果这是正确的,您可以在_entry上存储指向外部状态机
的指针,或者在那里提取x的值并将其记录在子机中。

如果有一种方法可以实现我想要实现的目标?@Kam:您需要在某个地方实例化一个
子机
?如何做到这一点?它将如何绑定到特定的
FSM
对象?@Kam:好的。同样的原则也适用。无论何时构造
子机
实例,都需要将引用传递给
FSM
实例。(不过,我对Boost库不太熟悉,所以可能是API的某些方面让这个问题变得棘手。)@Kam:你刚才说的一个字我都听不懂。你应该提出一个新问题我在Boost.MSM文档的状态机(和子机)构造中发现了一个注释-希望它对OP比对我更有意义不幸的是,内部结构的实例声明为运行时(事件),因此我只能定义类型,并且不能为它们实例化对象不带
FSM
对象。这是如何回答这个问题的?谢谢!这就是我一直在寻找的,现在我真的明白了。这篇文章和奥利的文章是为我写的。我希望我能接受这两个答案。