2011-07-31 46 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