I am looking for a solution to the following problem:
I have a class X with (assuming) only protected members. And I have a set S of several classes 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) :
- Any instance
sof a class of the set S, in relation with (depending on)x, must have access toprotectedmembers ofx. - Access to
protectedmembers ofxmust be restricted tos(andx). - Creation and destruction of instance
smust keep instancexalive and unaltered.
Additionally, at a given time, only one instance s [in relation] with x is existing.
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.
In addition, the following requirements must be met:
Xmust be considered non-copyable and non-movable.- A solution involving wrapper to
protectedmembers ofX, though acceptable, is not desirable due to maintenance cost. - Making all classes of set
Sfriends ofXis obviously not acceptable (to many classes).
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, e.g.:
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:
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. Thanks for your help.
Rationale:
To clarify where this problem comes from and in which way a solution will help me improve my code:
- Every classes of the set S represent states of a state-machine (which state-machine is in some way inspired from the State pattern from the Gang of 4).
- Each state must have access to a common underlying sub-object (the instance of
X) which implements all sort of works (algorithms, i/o, and so on...) - When a new state is entered, an object of the proper class in set S is created; when the state is exited, the object is destroyed, then replaced by a new one (a new state). The instance of
Xmust not be altered in this switch.