2010-01-27 97 views
2

假设我有两个班级Foo和Bar,并且我想在不改变Foo的情况下让Foo成为Bar的朋友。这是我的尝试:朋友mixin模板?

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; 
} 

获取编译器有关尝试调用私有函数的错误,所以显然它不起作用。有任何想法吗?

+1

+1:“友善foo” - 我挖的那个声音:> – 2010-01-27 10:24:59

+2

友谊不是遗传 – 2010-01-27 10:35:39

+0

我不是那么想。 – drby 2010-01-27 10:37:32

回答

2

它不起作用,因为friends无论如何都无法访问privateFunction,因为它是private(后代类无论如何都无法访问私有字段)。如果您要将privateFunction声明为protected,那么它将起作用。

这是关于C++中Mixins的nice paper。 (PDF链接)

+0

Duh。我认为我错过了一些明显的东西。感谢您指出。 – drby 2010-01-27 10:35:22

+0

@drby:但请注意,David的答案仍然存在 - 它在标准中是不允许的(我对此表示赞同),因此在编译器之间可能无法移植。 – 2010-01-27 10:56:49

1

只有一个班级可以宣布他的朋友是谁。它们不能从外部注入。这很明显:如果语言允许,它可能完全忘记private关键字,毕竟任何用于访问私有成员的代码都可以使用该技巧。请注意,在派生对象中添加朋友关系将无济于事,因为该方法无法从派生模板中访问。

你可以尝试的任何其他方法都是hackery和non-portable(重写相同的头文件private对于public在许多情况下似乎都有效,但在某些情况下会失败)。

另请注意,在类模板中,不能将类型参数声明为朋友,即使即将在标准中删除该限制,也会在当前标准中明确禁止。

0

你或许应该让

void privateFunction(){} 

保护。

哎呀,我忘了你不能修改Foo。没有其他办法可以做,afaik。