2013-01-03 100 views
0

我想初始化一個對象中的成員(引用類型),指向另一個對象(不同類型)的私有成員。我使用friend爲私人會員提供訪問權限。 (請耐心等待,我進一步解釋爲什麼我需要這樣做。)初始化朋友的引用成員到類私人成員

下面是我嘗試着手使用的代碼的最低版本,它顯然不起作用。現在很清楚,我只是試圖用這個代碼Aries a(t.Leo);初始化引用,但是因爲這是在main()內完成的,所以它不能編譯。

我在這裏和在互聯網上經歷了許多帖子(關於friendreference的主題),但找不到解決問題的方法。我怎麼能做這個工作,或者我可以嘗試使用其他方法來正確綁定引用?

class Aries; 

class Taurus { 
friend class Aries; 
public: 
    void setLeo(int inLeo) { 
    Leo = inLeo; 
    } 

private: 
    int Leo; 
}; 

class Aries { 
public: 
    Aries(const int& inCancer) : Cancer(inCancer) {} 

private: 
    const int& Cancer; 
}; 

int main() { 
    Taurus t; 
    Aries a(t.Leo); // Intention: initialize (bind) the Cancer member with t's Leo. 
} 

注意我知道足夠的C++理解爲什麼上述做法被認爲是可疑的或壞的。

我正在研究一個硬件模擬環境中的研究項目,其中測試平臺是用C++編寫的。該項目的目標是將班級(私人)成員顯示爲波形。這樣做的唯一可靠方法是將「波形制造者」類作爲測試臺對象的friend,然後讓它「追蹤」私有成員(通過創建如上所述的reference)。在測試平臺中提供getter方法的另一種方法是不切實際的,因爲這個項目將使用20年的遺留代碼。

+0

耐人尋味的名稱混淆... – Chowlett

+0

@Chowlett哈哈,富酒吧巴茲是不夠的時候。 –

回答

1

我知道你知道friend是值得商榷的,但有時是必要的,但在這種情況下,這些類沒有成爲朋友。

struct AriesBinder { 
    AriesBinder(const int& c) : Cancer(c) {} 
    const int& Cancer; 
}; 

class Taurus { 
public: 
    void setLeo(int inLeo) { 
    Leo = inLeo; 
    } 

    AriesBinder bind() const { return AriesBinder(Leo); } 

private: 
    int Leo; 
}; 

class Aries { 
public: 
    Aries(const int& inCancer) : Cancer(inCancer) {} 
    Aries(AriesBinder b) : Cancer(b.Cancer) {} 

private: 
    const int& Cancer; 
}; 

int main() { 
    Taurus t; 
    Aries b(t.bind()); // Intention was made clear 
} 

,這是特別有用的,如果像Taurus許多對象可以綁定到Aries。此外,它將這兩個類別分開,因爲現在不需要彼此瞭解,因此您可以更改Taurus的內部表示。

+0

你的推理是有效的和有用的。我遇到的問題是我必須對「金牛座」類(這是客戶的代碼)進行最小限度的更改。我最初努力弄清楚這是否可以在沒有任何代碼改變的情況下完成,但由於沒有符合標準的訪問私人成員的方法(並且這是一個騙局,即使有可能通過一些黑客),我只做一個更改(添加朋友聲明)。我個人更喜歡非朋友版本(如您的代碼),但業務考慮因素會覆蓋工作中的技術版本。 :S –

2

只需更改Aries構造函數即可直接使用Taurus引用,而不是私有的int。像這樣:

class Aries; 

class Taurus { 
friend class Aries; 
public: 
    void setLeo(int inLeo) { 
    leo = inLeo; 
    } 

private: 
    int leo; 
}; 

class Aries { 
public: 
    Aries(const Taurus& inTau) : Cancer(inTau.leo) {} 

private: 
    const int& Cancer; 
}; 

int main() { 
    Taurus t; 
    Aries a(t); 
} 
0

友誼的目的是允許訪問與你緊密耦合的某些類,通常是類工廠(在構建類時分配成員)或一些特殊的實現類。

因此,在你的情況下,如果白羊座是金牛座的朋友,你會期待這兩者之間有很強的耦合。

你的代碼不起作用,因爲你是從main,而不是從白羊座訪問Taurus.Leo。

友誼的目的特別是不必爲這些變量創建一個公共的「getter」。這是因爲這些變量是「內部細節」,您不希望整個公衆訪問,甚至不需要閱讀。

因此,雖然我希望大多數的答案以上是可能的解決方案,並編制和工作,你必須明白友誼和設計理念,爲您的具體情況,看它是否是一個合適的使用。

+0

雖然我不是C++專家,但我知道這一點,並且同意你所說的所有內容。但問題是我沒有設計模擬環境的其餘部分。最初的建築是20多年前設計的。如果當時已經考慮過這個項目,他們可能會設計成可以避免友誼,但現在我的任務主要是在20年的遺留代碼中「修補」一項新功能。正如你可以想象的那樣,它會變得醜陋,但我試圖儘可能減少醜陋。 –