2010-01-27 144 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。