说我有一个令人难以置信的设计类定义如下:
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;
};
我希望Outer
成为唯一能够构造Inner
实例的类,但是当传递对{的引用时,其他类/函数可以访问_inner.foo
{1}}到_inner
。这可能吗?有没有更好的方法来实现同等功能?
答案 0 :(得分:6)
我知道有两个解决这个问题的方法,我想展示和比较。
解决方案1(friend
):
使用friend
关键字,您可以允许其他类访问您的私有函数。 (小心使用。)
您可以将Inner
的构造函数设为私有,但将Outer
设为Inner
的朋友。请注意,Inner
不仅可以调用构造函数,还可以调用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;
};
解决方案2(访问密钥):
没有friend
但稍微复杂一点的另一种方法是给构造函数一个只有Outer
能够构造的参数(比如&#34; key&#34;)。然后构造函数是公共的,但其他类将无法调用它,因为它们无法提供执行此操作所需的参数:
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;
};
请注意,虽然这看起来会增加性能开销,但事实并非如此。所有内容都经过优化,仅用于在编译过程中捕获访问违规行为。
<强>比较强>
解决方案2的优势在于Inner
仅授予Outer
访问构造函数的权限。所以只要你想拥有真正的&#34; Inner
中的私有函数(Outer
甚至无法访问),这是一个很好的解决方案。但解决方案1更容易编写和理解(快速和脏,可以这么说)。