C ++ Friend Синтаксис / Семантика Вопрос - PullRequest
2 голосов
/ 31 июля 2011

Мой код был рассмотрен на: https://codereview.stackexchange.com/questions/3754/c-script-could-i-get-feed-back/3755#3755

Использовалось следующее:

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

Ответы [ 3 ]

1 голос
/ 31 июля 2011

Вы можете сделать это без дружественных функций, определив 'getters' для ваших переменных-членов 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() << " ";
}

Выберите, оба действительны.

1 голос
/ 31 июля 2011

А как клиент может получить к ним доступ, если они являются частными, используя следующее?

Да. Поскольку friend функции не являются членами класса, не имеет значения, где вы их определяете или объявляете. Любой может их использовать. Правила доступа к ним не применяются.

Может ли кто-нибудь объяснить, что именно возвращается?

operator>>() возвращает std::istream&, что является ссылкой на входной поток. И operator<<() возвращает std::ostream&, что является ссылкой на выходной поток.

Есть ли другой способ сделать это, не назначая их функциями друзей?

Да. Есть выход. Вы можете добавить две функции-члена input и output в раздел 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);
}
0 голосов
/ 31 июля 2011

Функция друга не зависит от класса, но ей разрешен доступ к закрытым членам.

В вашем классе нет способа доступа к x и y членам (и это делает класс сортировочным).бесполезно, кстати), чтобы иметь возможность обрабатывать чтение / запись экземпляров в поток, эти функции должны быть объявлены друзьями.

Если вы никогда раньше не видели концепцию friend, то, вероятно, означает, что вы пытаетесьнаучить себя C ++, написав код.Это ужасная идея ... C ++ не может быть изучен таким образом по многим различным причинам.

Выберите хорошую книгу и прочитайте ее от корки до корки, а затем поэкспериментируйте с ней.На сегодняшний день это самый быстрый (единственный) способ.

Неважно, насколько вы умны (на самом деле, вы умнее и труднее будет изучать C ++ экспериментально: логика не всегда помогает в этомместо).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...