2011-07-31 87 views
2

我的代碼是在審查: https://codereview.stackexchange.com/questions/3754/c-script-could-i-get-feed-back/3755#3755C++朋友語法/語義問題

以下使用:

class Point 
{ 
    public: 
    float distance(Point const& rhs) const 
    { 
     float dx = x - rhs.x; 
     float dy = y - rhs.y; 

     return sqrt(dx * dx + dy * dy); 
    } 
    private: 
     float x; 
     float y; 
     friend std::istream& operator>>(std::istream& stream, Point& point) 
     { 
      return stream >> point.x >> point.y; 
     } 
     friend std::ostream& operator<<(std::ostream& stream, Point const& point) 
     { 
      return stream << point.x << " " << point.y << " "; 
     } 
}; 

由另一個構件。我不明白朋友的功能在做什麼。有沒有另一種方法來做到這一點,而不使他們的朋友功能?客戶如何使用以下方式訪問他們?有人能說明究竟返回什麼嗎?

int main() 
{ 
    std::ifstream  data("Plop"); 

    // Trying to find the closest point to this. 
    Point first; 
    data >> first; 

    // The next point is the closest until we find a better one 
    Point closest; 
    data >> closest; 

    float bestDistance = first.distance(closest); 

    Point next; 
    while(data >> next) 
    { 
     float nextDistance = first.distance(next); 
     if (nextDistance < bestDistance) 
     { 
      bestDistance = nextDistance; 
      closest   = next; 
     } 
    } 

    std::cout << "First(" << first << ") Closest(" << closest << ")\n"; 
} 

回答

1

又如何可以在客戶端訪問他們時,他們使用的專用以下?

是的。由於friend函數不是成員的類,所以您定義它們或聲明它們並不重要。任何可以使用它們。訪問規則不適用於它們。

有人能說明究竟是什麼被返回?

operator>>()返回std::istream&它是對輸入流的引用。 和operator<<()返回std::ostream&這是參考輸出流。

有沒有另一種方法來做到這一點,而不使他們的朋友功能?

是的。有一種方法。您可以添加兩個成員函數inputoutput到類的public部分,它會做什麼friend功能,現在正在做的,你可以讓operator<<operator>>非友元函數如下:

class Point 
{ 
    public: 
    //.... 
    std::istream& input(std::istream& stream) 
    { 
     return stream >> point.x >> point.y; 
    } 
    std::ostream& output(std::ostream& stream) const 
    { 
     return stream << point.x << " " << point.y << " "; 
    } 
    //... 
}; 

std::istream& operator>>(std::istream& stream, Point& point) 
{ 
    return point.input(stream); 
} 
std::ostream& operator<<(std::ostream& stream, Point const& point) 
{ 
    return point.output(stream); 
} 
+1

@ Nawaz謝謝,我需要回顧一下Stroustrup的書。你瞭解正在返回的內容的語法嗎? –

+1

@ Nawaz再次感謝,據說,我明白返回的類型,但它是返回這種類型的語義/功能。我假設stream >> point.x >> point.y從流構造函數中的文件讀入x和y成員變量。但爲什麼要退貨呢,爲什麼不把它留在那呢? –

+0

@Matthew:你返回它表明你可以寫'stream << point1 << point2',也就是說,你可以在* chain *調用中使用它。 – Nawaz

0

朋友函數獨立於類,但被允許訪問私有成員。

在你們班有沒有辦法訪問xy成員(這使得該類那種無用的,順便說一句),所以能夠處理讀實例/寫入流這些功能必須申報朋友。

如果你以前從未看過friend的概念,那麼可能意味着你正試圖通過編寫代碼來教自己C++。這是一個可怕的想法......由於許多不同的原因,C++無法以這種方式學習。

選擇a good book並閱讀它的封面,然後進行實驗。這是迄今爲止最快(唯一)的方式。

無論你多聰明(實際上你越聰明,通過實驗學習C++越困難:邏輯在這個地方並不總是幫助)。

+0

「如果你以前從來沒有見過朋友的概念,那麼可能意味着你正試圖通過編寫代碼來教自己C++,這是一個可怕的想法......由於許多不同的原因,C++無法以這種方式學習。我之前見過的朋友,我已經使用了幾次,但不是100%熟悉它的語義。我也讀了很多C++。我讀然後玩,讀更多然後玩。但是,我發現行業內其他人的意見有很大幫助。在C++之外,我沒有真正的生活經驗,所以我仍然在學習。感謝您的輸入,但。 –

+0

「戲劇」部分當然非常重要;人們會通過閱讀/寫作而不是通過閱讀來學習10倍以上的概念。 C++的問題在於,在很多地方,語言是「不合邏輯的」(主要是出於歷史原因),所以邏輯推理根本無濟於事,會誤導你。這一事實與C++的主要哲學思想相結合,即程序員沒有犯錯(因此我們在C++中使用「未定義行爲守護進程」而不是「運行時錯誤天使」)應該明確爲什麼試驗只是自殺。 – 6502

1

您可以通過定義「干將」你X和Y的成員變量和一個合適的構造函數,這樣

class Point 
{ 
public: 
    Point(float xx, float yy) : x(xx), y(yy) {} 

    float getX() const { return x; } 
    float getY() const { return y; } 
private: 
    float x; 
    float y; 
}; 

std::istream& operator>>(std::istream& stream, Point& point) 
{ 
    float x, y; 
    stream >> x >> y; 
    point = Point(x, y); 
    return stream; 
} 
std::ostream& operator<<(std::ostream& stream, const Point& point) 
{ 
    return stream << point.getX() << " " << point.getY() << " "; 
} 

隨你挑做這個沒有朋友的功能,都是有效的。

+0

'operator >>'無效。嘗試編譯它。 – Nawaz

+0

是的,你是對的。垃圾回答,我該如何刪除它? – jahhaj

+0

你沒有刪除選項?只需在帖子的底部看到即可。你已經鏈接|編輯|刪除|標記選項。 – Nawaz