[英]Unable to access members of including class from a polymorphic nested classes
A nested class Foo::Utility
has access to another nested class Foo::Container
even if the later is private.一个嵌套的 class
Foo::Utility
可以访问另一个嵌套的 class Foo::Container
,即使后者是私有的。 I am trying to extend this access to a polymorphic version UtilityPrint
of Foo::Utility
without success:我试图将此访问扩展到
Foo::Utility
的多态版本UtilityPrint
,但没有成功:
class Foo {
private:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
// works even if Container is private
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
// polymorphic nested class
// failed attempt
class UtilityPrint : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
// this does not work, because Foo::Container is private
}
};
Is there a correct way to achieve this, or is this a bad idea to begin with?有没有正确的方法来实现这一点,或者这是一个坏主意?
The error message I get is this:我得到的错误信息是这样的:
error: ‘class Foo::Container’ is private
class Container {};
^
error: within this context
virtual void action(Foo::Container &) {
Also, Here is my reason for using this somewhat weird design: I wanted a container
and a polymorphic utility
that does things to both the container and Foo
.另外,这是我使用这种有点奇怪的设计的原因:我想要一个
container
和一个多态utility
,它可以同时对容器和Foo
执行操作。 Since both container
and utility
would only be used within the context of Foo
, I put the two classes into Foo
.由于
container
和utility
都只能在Foo
的上下文中使用,因此我将这两个类放入Foo
中。
EDIT: I can wrap the derived Utility
in a derived Foo
, and the code compiles:编辑:我可以将派生的
Utility
包装在派生的Foo
中,并且代码编译:
class Foo {
protected:
class Container {};
public:
class Utility {
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class FooPrint : public Foo {
public:
class Utility : Foo::Utility {
public:
virtual void action(Foo::Container &) {
/* Implementation */
}
};
};
This however introduces a wrapper class FooPrint
which exists only for syntactic reasons and is (being a derived class.) never meant to be instantiated, I don't like this approach for this reason.然而,这引入了一个包装器 class
FooPrint
,它仅出于句法原因而存在,并且(作为派生的 class。)从未打算实例化,因此我不喜欢这种方法。 but I can be very wrong on this regard.但在这方面我可能是非常错误的。
Access is not inherited.访问不被继承。 This is more often brought up when discussing friends , but it applies here as well.
这在讨论朋友时经常被提起,但在这里也适用。
First, let's look at why Foo::Utility::action
can access the private class Foo::Container
.首先,让我们看看为什么
Foo::Utility::action
可以访问私有的 class Foo::Container
。 Actually, it's right there in the names.实际上,它就在名称中。 The
Foo::Container
can only be accessed by members of Foo
, and members of Foo
can be recognized when you write out their qualified names and that name starts with " Foo::
". Foo::Container
只能由Foo
的成员访问,并且Foo
的成员可以在您写出其限定名称并且该名称以“ Foo::
”开头时被识别。
In contrast, UtilityPrint
is not a member of Foo
.相反,
UtilityPrint
不是Foo
的成员。 (In fact, it would be a huge security violation if someone could simply say "oh, yeah, I'm a member too!" and get access to your private information.) So while UtilityPrint
has (protected) access to Foo::Utility
, it does not have access to everything to which Foo::Utility
has access. (事实上,如果有人可以简单地说“哦,是的,我也是会员!”并访问您的私人信息,那将是一个巨大的安全违规。)因此,虽然
UtilityPrint
具有(受保护)访问Foo::Utility
,它无法访问Foo::Utility
可以访问的所有内容。
If Foo::Utility
desires to extend its access to classes derived from it, it would need to explicitly do so.如果
Foo::Utility
希望扩展其对派生自它的类的访问,则需要显式地这样做。 One way to do this is by creating an alias.一种方法是创建别名。
class Utility {
protected:
using Container = Foo::Container; // Derived classes can access this.
public:
virtual void action(Container &) = 0;
virtual ~Utility() {} // <-- remember to properly support polymorphism
};
That still leaves open the question of whether or not this is good design.这仍然留下了这是否是好的设计的问题。 I would consider this a warning flag that something might be off, but not conclusively so.
我会认为这是一个警告标志,表明某些事情可能已关闭,但并非最终如此。 The question does not have enough context for me to make this sort of call.
这个问题没有足够的背景让我做出这种呼吁。 I would just give you the guideline that if you feel like you are circumventing a lot of language features (like private access), then maybe the design needs work.
我只想给你一个指导方针,如果你觉得你正在绕过很多语言特性(比如私人访问),那么也许设计需要工作。
I adopted this solution :我采用了这个解决方案:
class Foo {
protected:
class Container {};
public:
class Utility {
protected:
typedef Container FooContainer;
public:
virtual void action(Container &) = 0;
};
Container container;
Utility * utility;
Foo(Utility * utility): container(), utility(utility) {};
void performAction() {
utility -> action(container);
}
};
class UtilityPrint : Foo::Utility {
public:
virtual void action(FooContainer &) {
/* implementation */
}
};
When the name FooContainer
is introduced using typedef
, accessibility is applied to that name only, with no regard of it actually referring to Foo::Container
.当使用
typedef
引入名称FooContainer
时,可访问性仅应用于该名称,而不考虑它实际上指的是Foo::Container
。 This allows all derived Utility
to reference Foo::Container
by naming FooContainer
.这允许所有派生的
Utility
通过命名FooContainer
来引用Foo::Container
。
I believe this also applies to using
我相信这也适用于
using
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.