Limit constructor scope in nested struct
c++, c++11
Solution
I'm aware of two solutions to such a problem which I'd like to demonstrate and compare.
Solution 1 (`friend`):
Using the `friend` keyword, you can allow another class to access your private functions. (Use carefully.)
You can make the constructor of `Inner` private, but make `Outer` a friend of `Inner`. Note that not only the constructor but any private method of `Inner` can be called by `Outer`.
class Outer {
public:
class Inner {
friend class Outer; // <<---- friend
// private to Inner but also callable by Outer (because it's a friend):
Inner(int innerValue) : foo(innerValue) {};
public:
// (add public methods here)
int foo;
};
Outer(int innerValue) : _inner(innerValue) {};
const Inner& getInner() const {
return _inner;
};
private:
Inner _inner;
};
Solution 2 (access keys):
A different approach without `friend` but slightly more complex is to give the constructor a parameter which only `Outer` is able to construct (like a "key"). The constructor is then public, but other classes will not be able to call it since they can't provide the arguments required to do so:
class Outer {
// Our dummy struct which is only constructible by Outer:
struct ConstructInnerKey {
// Empty
};
public:
struct Inner {
Inner(int innerValue, Outer::ConstructInnerKey) : foo(innerValue) {};
// ^^^^^^^^^^^^^^^^^^^^^^^^
// a key is required (but not used)
// to construct an instance of Inner
// (add public methods here)
int foo;
};
Outer(int innerValue) : _inner(innerValue, Outer::ConstructInnerKey()) {};
// ^^^^^^^^^^^^^^^^^^^^^^^^^^
// make a key and pass it to Inner
const Inner& getInner() const {
return _inner;
};
private:
Inner _inner;
};
Note that while this looks like it adds a performance overhead, this is not the case. Everything is optimized away and only serves for catching access violations during compilation as you'd like to.
Comparison:
Solution 2 has the advantage that `Inner` only grants `Outer` to access the constructor. So as long as you want to have "truly" private functions in `Inner` (not even accessible by `Outer`), this is a good solution. But solution 1 is a lot easier to write and understand (quick and dirty, so to speak).
Problem
Say I have an incredibly contrived class defined as follows: ``` class Outer { public: struct Inner { Inner(int innerValue) : foo(innerValue) {}; int foo; }; Outer(int innerValue) : _inner(innerValue) {}; const Inner& getInner() const { return _inner; }; private: Inner _inner; }; ``` I want `Outer` to be the only class capable of constructing an instance of `Inner`, but in such a way that other classes/functions can access `_inner.foo` when passed a reference to `_inner` through `Outer::getInner()`. Is this possible? Is there a better way of achieving equivalent functionality?