我正在处理一些代码,我遇到了与此类似的情况:
struct Bar;
struct Foo{
friend struct Bar;
private:
Foo(){}
void f(){}
void g(){}
};
struct Bar {
Foo* f;
Bar() { f = new Foo();}
~Bar() { delete f;}
};
int main(){
Bar b;
}
我希望Bar
不是friend
的{{1}},因为除了Foo
之外,构造函数Foo
不需要访问任何Bar
1}}私有方法(因此不应该有访问权限)。有没有办法只允许Foo
创建Bar
而不让他们成为朋友?
PS :意识到问题可能不是100%明确。我不介意是否是通过朋友,只是所有Foo
都可以访问所有私人方法的事实令我感到不安(这通常是Bar
的情况),这就是我的意思我想避免。幸运的是,到目前为止,没有一个答案对这个糟糕的表述有问题。
答案 0 :(得分:9)
这正是attorney-client成语的用语:
struct Bar;
struct Foo {
friend struct FooAttorney;
private:
Foo(){}
void f(){}
void g(){}
};
class FooAttorney {
static Foo* makeFoo() { return new Foo; }
friend struct Bar;
};
struct Bar {
Foo* f;
Bar() { f = FooAttorney::makeFoo();}
~Bar() { delete f;}
};
int main(){
Bar b;
}
在一个模仿生活方式的代码中,该类宣布了一名律师,该律师将调解其愿意与选定的一方分享的秘密。
答案 1 :(得分:5)
如果你不想引入另一个类,你可以缩小友谊圈,并使Bar
的构造函数Foo
成为朋友。它要求Bar
的{{1}}定义可供Foo
使用,它仍然允许Bar
的构造函数无限制地访问Foo
的私有实现:
struct Foo;
struct Bar {
Foo* f;
Bar();
~Bar();
};
struct Foo{
friend Bar::Bar();
private:
Foo(){}
void f(){}
void g(){}
};
Bar::Bar() : f(new Foo()) {
}
Bar::~Bar() {
delete f;
}
这并不能达到你想要的效果,但它使友谊更具针对性。
答案 2 :(得分:3)
我遇到的一种方法是让内部class
使Bar
成为其朋友,这样只有Bar
可以创建它,内部class
可以用作Foo
构造函数的附加参数,因此只有class
的朋友可以调用它。
class Foo
{
public:
// only friends of the special key can invoke the constructor
// or any member function that includes it as a dummy parameter
class special_key {friend class Bar; special_key(){}};
// making special_key a dummy parameter makes sure only friends of
// the special key can invoke the function
Foo(special_key) {}
void f(){}
void g(){}
};
class Bar
{
public:
// only Bar functions can create the special key
Bar() { f = std::make_unique<Foo>(Foo::special_key()); }
private:
std::unique_ptr<Foo> f;
};
除了限制对特定功能的访问之外,这种技术还允许使用智能指针make
功能,这种功能不会引导友谊。