C++ 内部类访问外部类
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11405069/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Inner class accessing outer class
提问by Kam
I am relatively new to C++, and I have looked a lot for an answer for this thing but I never got a satisfying answer.
我对 C++ 比较陌生,我已经寻找了很多关于这件事的答案,但我从来没有得到满意的答案。
Let's say I have a structure called FSM
. Eventually in my code, multiple instances of FSM
can be created. One of FSM
's attributes is int X
which is not static, every instance of FSM
should have its own value for X
.
假设我有一个名为FSM
. 最终在我的代码中,FSM
可以创建多个实例。其中一个FSM
的属性是int X
它不是一成不变的,每个实例FSM
应该有其存在的价值X
。
Now, one of FSM
's attributes is another structure submachine
which needs to read the value of X
like this:
现在, 的一个FSM
属性是另一个结构submachine
,它需要X
像这样读取 的值:
struct FSM
{
public:
int x;
int getX(){return x;}
struct submachine
{
void onentry() {int g = getX();};
};
};
This gives the following error:
这给出了以下错误:
Error: 'FSM::getX' : illegal call of non-static member function
错误:'FSM::getX':非静态成员函数的非法调用
My question is, submachine
is a member of FSM
, so shouldn't it have access to local instances of all the attributes of FSM
? And if not, when we create an instance of FSM
, wouldn't we be creating an instance of all its members i.e. submachine
? And if so, then why do we need to create an object that onentry()
needs?
我的问题是,它submachine
是 的成员FSM
,所以它不应该访问 的所有属性的本地实例FSM
吗?如果没有,当我们创建 的实例时FSM
,我们是否会创建其所有成员的实例,即submachine
?如果是这样,那为什么我们需要创建一个需要的对象onentry()
?
I am assuming the compiler is correct, so I would also want to know if there's a way to make this work.
我假设编译器是正确的,所以我也想知道是否有办法让这个工作。
NOTE: Unfortunately, the instances of the inner structures (submachine
) are instantiated when an event is called and thus I can only define the type, and not instantiate objects for them in FSM
.
注意:不幸的是,内部结构 ( submachine
) 的实例在调用事件时被实例化,因此我只能定义类型,而不能在FSM
.
回答by Oliver Charlesworth
my question is, submachine is a member of FSM, so it should have access to local instances of all the attributes of FSM, no?
我的问题是,submachine 是 FSM 的成员,所以它应该可以访问 FSM 的所有属性的本地实例,不是吗?
No. Unlike in Java, inner class objects don't have an implicit reference to an outer object.
不。与Java 不同,内部类对象没有对外部对象的隐式引用。
wouldn't we be creating an intance of all its members i.e. submachine?
我们不会创建其所有成员的实例,即 submachine?
submachine
is a type, not a member variable. If you wanted a member variable, you'd have to do something like this:
submachine
是类型,而不是成员变量。如果你想要一个成员变量,你必须做这样的事情:
struct FSM {
struct submachine {
...
};
submachine sm; // Member variable of type submchine
};
And if you want sm
to "see" its parent object, you'll need to pass it explicitly:
如果你想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
};
Note that the same principle applies for instances of submachine
that aren't member variables. If you want them to be able to access an FSM
instance, you'll need to pass a reference to one.
请注意,相同的原则适用于submachine
非成员变量的实例。如果您希望它们能够访问FSM
实例,则需要传递对实例的引用。
Note also that you could use a pointer rather than a reference. In fact, a pointer offers greater flexibility in many cases.
另请注意,您可以使用指针而不是引用。事实上,指针在许多情况下提供了更大的灵活性。
回答by Useless
consider that in your example, I can legally write a free function
考虑在你的例子中,我可以合法地编写一个免费的函数
void foo()
{
FSM::submachine sub;
sub.onentry();
}
where there is noFSM instance that sub
could refer to.
其中没有sub
可以引用的FSM 实例。
Either, as Oli says, have the submachine
object store a reference to its parent FSM
object, or perhaps just pass the value of x
directly into onentry
(it isn't clear how it gets invoked).
或者,正如 Oli 所说,让submachine
对象存储对其父FSM
对象的引用,或者可能只是将 的值x
直接传递到onentry
(尚不清楚它是如何被调用的)。
From a quick look at the Boost.MSM docsI found this note on non-default-constructed submachines.
通过快速浏览Boost.MSM 文档,我发现了关于non-default-constructed submachines 的注释。
It's pretty ugly, I don't understand the backend enough to paraphrase it here, and the literal code won't make enough sense in isolation to be worth pasting.
它非常丑陋,我对后端的理解不够充分,无法在此处对其进行解释,而且文字代码单独来看也没有足够的意义值得粘贴。
The example code linked from there also shows the submachine's entry method with the following signature:
从那里链接的示例代码还显示了具有以下签名的子机器的输入方法:
template <class Event,class FSM> void on_entry(Event const&,FSM& );
if that's accurate, you can either store a pointer to your outer state machine on_entry
, or extract the value of x there and record it in the submachine.
如果这是准确的,您可以存储一个指向外部状态机的指针on_entry
,或者在那里提取 x 的值并将其记录在子机中。
回答by Kevin Grant
Note that declaring struct submachine
only defines the type; it does not actually create a field in the class of that type.
请注意,声明struct submachine
仅定义类型;它实际上并未在该类型的类中创建字段。
You would need one of the following:
您将需要以下其中一项:
struct submachine mysub; // creates a field after the class is defined
or
或者
struct submachine
{
. . .
} mysub; // creates the field "mysub" also, as the structure is being defined
This makes mysub
the field, and you then access it in the same way that you'd access x
.
这将创建mysub
该字段,然后您可以像访问x
.
The definition of submachine
needs to include a specific FSM
(e.g. a pointer field FSM*
, and probably a constructor like submachine(FSM* fsm): fsm_(fsm) {}
to initialize it) so that you can say fsm_->getX()
to access a certain X
value.
定义submachine
需要包含一个特定的FSM
(例如一个指针字段FSM*
,可能还有一个构造函数submachine(FSM* fsm): fsm_(fsm) {}
来初始化它),以便您可以fsm_->getX()
访问某个X
值。
回答by jxh
I am only making a guess at what you want to do, but if my guess is correct, you might be thinking of something like the below.
我只是猜测您想做什么,但如果我的猜测是正确的,您可能会想到以下内容。
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; }
};