朋友混入模板?
假设我有两个类 Foo 和 Bar,我想在不改变 Foo 的情况下使 Foo 与 Bar 成为朋友。这是我的尝试:
class Foo
{
public:
Foo(){}
private:
void privateFunction(){}
};
template <class friendly, class newFriend>
class friends : public friendly
{
private:
friend newFriend;
};
class Bar
{
public:
Bar(){}
void callFriendlyFunction()
{
friendlyFoo.privateFunction();
}
private:
friends<Foo, Bar> friendlyFoo;
};
int main(int argc, char* argv[])
{
Bar bar;
bar.callFriendlyFunction();
return 0;
}
关于尝试调用私有函数出现编译器错误,所以显然它不起作用。有什么想法吗?
Let's say I have two classes Foo and Bar, and I want to make Foo friends with Bar without changing Foo. Here's my attempt:
class Foo
{
public:
Foo(){}
private:
void privateFunction(){}
};
template <class friendly, class newFriend>
class friends : public friendly
{
private:
friend newFriend;
};
class Bar
{
public:
Bar(){}
void callFriendlyFunction()
{
friendlyFoo.privateFunction();
}
private:
friends<Foo, Bar> friendlyFoo;
};
int main(int argc, char* argv[])
{
Bar bar;
bar.callFriendlyFunction();
return 0;
}
Getting a compiler error about trying to call a private function, so apparently it didn't work. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
它不起作用,因为
friends
无论如何都无法访问privateFunction
,因为它是private
(后代类无论如何都无法访问私有字段) 。如果您将privateFunction
声明为protected
,它就会起作用。这是一篇关于 C++ 中 Mixin 的好论文。 (PDF链接)
It doesn't work, because
friends
has no access toprivateFunction
anyway, because it'sprivate
(descendant classes have no access to private fields anyway). If you would declareprivateFunction
asprotected
, it would work.Here's a nice paper about Mixins in C++. (PDF link)
只有一个类可以声明它的朋友是谁。它们不能从外部注射。这很简单:如果语言允许,它可能会完全忘记 private 关键字,毕竟任何旨在访问私有成员的代码都可以使用该技巧。请注意,在派生对象中添加好友关系不会有帮助,因为无法从派生模板访问该方法。
您可以尝试的任何其他方法都是黑客行为且不可移植(重写相同的标头,将
private
更改为public
似乎在许多情况下都有效,但在某些情况下会失败极端情况)。另请注意,在类模板中,您不能将类型参数声明为友元,当前标准中明确禁止这样做,即使该限制将在即将推出的标准中删除。
Only a class can declare who its friends are. They cannot be injected from outside. This just makes plain sense: if it was allowed by the language, it might just forget about the private keyword at all, after all any code that intended on accessing the private members could just use that trick. Note that adding the friend relationship in a derived object will not help, as the method is not accessible from the derived template.
Any other approach you can try is hackery and non-portable (rewritting the same header changing the
private
forpublic
will seem to work in many situations, but it will fail in some corner cases).Also note that within a class template you cannot declare a type-argument as friend, it is explicitly prohibited in the current standard, even if that limitation will be removed in the upcoming standard.
您可能应该进行
保护。
哎呀,我忘了你不能修改 Foo。没有其他办法可以做到这一点,据我所知。
You should probably make
protected.
Ooops, I forgot you cannot modify Foo. No other way to do it, afaik.