[英]How to allow objects of some classes to access protected members of an object of another class
I am looking for a solution to the following problem: 我正在寻找以下问题的解决方案:
I have a class X
with (assuming) only protected
members. 我有一个
X
类,(仅假设) protected
成员。 And I have a set S of several classes A
, B
, C
, ... 我有几个班的集合S
A
, B
, C
,...
Assuming there is an existing instance x
of class X
members (which instance may be, either an instance of class X
, or a subset of an instance of any suitable container/derived-class/... depending on class X
) : 假设有一个现有实例
x
类的X
成员(其实例可以是任一类的一个实例X
,或任何合适的容器/派生类的一个实例的一个子集/ ...取决于类X
):
s
of a class of the set S , in relation with (depending on) x
, must have access to protected
members of x
. x
有关 (取决于x
)的集合S类的任何实例s
都必须有权访问x
protected
成员。 protected
members of x
must be restricted to s
(and x
). x
protected
成员的访问必须限于s
(和x
)。 s
must keep instance x
alive and unaltered . s
创建和销毁必须使实例x
保持生存且不变 。 Additionally, at a given time, only one instance s
[ in relation ] with x
is existing. 另外,在给定的时间,仅存在一个与
x
有关的实例s
[。
In other words and to clarify the above requirements: I need that any instance s
have access to protected
members of class X
, just like if (for example) classes of the set S were publicly derived from X
, except that the subset of members coming from class X
in inheritance must remain alive and unaltered whether instance s
is created or destroyed. 换句话说,并澄清了上述要求:我需要的任何实例
s
访问protected
类的成员X
,就像如果(例如)集合S被公开源自类X
,除了成员的子集来从类X
在继承必须保持活着 ,并没有改变实例是否s
创建或破坏。
In addition, the following requirements must be met: 另外,必须满足以下要求:
X
must be considered non-copyable and non-movable. X
必须被视为不可复制且不可移动。 protected
members of X
, though acceptable, is not desirable due to maintenance cost. X
protected
成员的解决方案由于维护成本而并不理想。 S
friends of X
is obviously not acceptable (to many classes). X
的集合S
所有类作为X
朋友显然是不可接受的(对于许多类而言)。 The currently implemented solution, that though does not fulfills requirement #5, is using composition and a parent class for classes of S friend of X
, eg: 当前实现的解决方案虽然不满足要求#5,但正在为
X
的S朋友的类使用组合和父类,例如:
class X
{
// public: int get_prot(); // not allowed (rq#2)
protected: int prot;
friend class Xaxx;
// friend A; friend B; ... // not acceptable (rq#6)
};
class Xacc
{
protected:
Xacc(X& x) : x(x) {}
int& x_prot() { return x.prot; } // not desirable (rq#5)
X& x;
};
class A : public Xacc
{
public:
A(X& x) : Xacc(x) {}
void work() { x_prot() = 1; }
};
Another interesting solution tested, that fulfills all requirements expect #4 though: 经过测试的另一个有趣的解决方案,可以满足所有要求,但是期望#4:
class A : public X
{
public:
A(const X& x) : X(x) {} // X not copyable (rq#4)
void work() { prot = 1; }
};
Any solution up to C++14 is acceptable. 最高可以支持C ++ 14的任何解决方案。 Thanks for your help.
谢谢你的帮助。
Rationale : 理由 :
To clarify where this problem comes from and in which way a solution will help me improve my code: 为了弄清楚这个问题的根源和解决方法,将有助于我改善代码:
X
) which implements all sort of works (algorithms, i/o, and so on...) X
的实例),该子对象可以实现各种工作(算法,I / O等)。 X
must not be altered in this switch. X
的实例不得在此开关中更改。 Is making the external class a friend of the class it needs access to out of the question? 是否使外部类成为了它所无法访问的类的朋友?
http://www.cplusplus.com/doc/tutorial/inheritance/ http://www.cplusplus.com/doc/tutorial/inheritance/
If your classes in S have a uniform interface that is simple (eg a single 'work' method), you can change your current implementation to fulfill requirement #5 by making Xacc a template class and by moving the implementation of the access to the protected parts of X into the specializations of Xacc. 如果您在S中的类具有简单的统一接口(例如,单个“工作”方法),则可以通过将Xacc设置为模板类并将访问权限的实现移至受保护对象来更改当前实现,以满足要求#5。 X的一部分变成Xacc的专业化。 It would look like this:
它看起来像这样:
class X
{
protected:
int prot;
template<typename State> friend class Xacc;
};
template<class State>
class Xacc
{
public:
Xacc(X &x) : x(x) {}
void work();
private:
X &x;
};
class S1;
template<> void Xacc<S1>::work()
{
x.prot = 1;
};
class S1: public Xacc<S1>
{
public:
S1(X &x): Xacc<S1>(x) {}
protected:
};
Perhaps you could use some variant of the passkey pattern 也许您可以使用密码模式的一些变体
class XKey {
XKey(){}
friend class Xacc;
};
class X {
public:
int& get_prot(XKey) { return prot; } // Only accessible to those who can construct XKey
protected:
int prot;
};
class Xacc {
protected:
Xacc(X& x) : x(x) {}
X& x;
XKey getKey() { return XKey(); }
};
class A : public Xacc {
public:
A(X& x) : Xacc(x) {}
void work() { x.get_prot(getKey()) = 1; }
};
int main() {
X x;
A a(x);
a.work();
//x.get_prot(XKey()) = 2; // Error: XKey::XKey() is private
}
I think the solution is: you have to have a base class for your set S
. 我认为解决方案是:必须为集合
S
提供一个基类。
S
can be your class X
or a separated (new) class from X
S
可以是你的类X
或从分开的(新)类X
software project is balance of requirement and design, when you listed all 6 requirements, the solution is limited to you have to have a base class Xacc
which has common functionality: access your X
软件项目是需求与设计之间的平衡,当您列出所有6个需求时,解决方案仅限于您必须拥有具有通用功能的基类
Xacc
:访问X
do you know story "castles in the air"? 你知道故事“空中的城堡”吗? how do I only have 2nd floor without 1st floor?
我如何只有2楼而没有1楼?
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.