Как я могу определить функцию-член друга для класса, который содержит не-ссылки / указатели этого класса? - PullRequest
0 голосов
/ 11 мая 2019

Если у меня есть два класса: один - Point, а второй - Square, Point содержит данные о членах: x и y, то они являются «частными» для представления координат точки.

Класс Square и аналогичные реализуют отношение "есть"; так, например, Square имеет четыре очка. По какой-то причине Point предоставляет доступ к своим личным данным через «дружбу»; но только для функции-члена print содержащих классов.

Проблема:

Класс Point должен видеть определение классов, например Square, чтобы он объявлял их члена печати как друга.

Square необходимо увидеть определение класса Point, чтобы он мог объявить экземпляры этого класса как свои члены.

Использование forward-декларации не решит проблему из-за того, что это все еще «неполный тип». Так как это можно решить?

class Square;
class Point{
    public:
        using pos = int;

        Point() = default;
        Point(pos, pos);

        pos getX()const{ return x_; }
        pos getY()const{ return y_; }
        void setX(pos x){ x_ = x; }
        void setY(pos y){ y_ = y; }

    private:
        pos x_{};
        pos y_{};

        // friend void Square::print()const; // the problem here. Square is still incomplete type
        // friend class Square; // we don't want this solution
};

inline Point::Point(pos x, pos y) :
    x_{ x },
    y_{ y }{

}

class Square{
    public:
        Square(const Point&, const Point&, const Point&, const Point&);

        Point getPtA()const{ return ptA_; }
        Point getPtB()const{ return ptB_; }
        Point getPtC()const{ return ptC_; }
        Point getPtD()const{ return ptD_; }
        void setPtA(const Point& ptA){ ptA_ = ptA; }
        void setPtB(const Point& ptB){ ptB_ = ptB; }
        void setPtC(const Point& ptC){ ptC_ = ptC; }
        void setPtD(const Point& ptD){ ptD_ = ptD; }

        void print()const;

    private:
        Point ptA_, ptB_, ptC_, ptD_;
};

Square::Square(const Point& ptA, const Point& ptB, const Point& ptC, const Point& ptD) :
    ptA_{ ptA }, ptB_{ ptB },
    ptC_{ ptC }, ptD_{ ptD }{

}

void Square::print()const{
    using pos = Point::pos;

    for(pos i{ptA_.x_}; i != ptB_.x_; ++i){
        for(pos j{ptA_.y_}; j != ptC_.y_; ++j)
            std::cout << "*";
        std::cout << std::endl;
    }
}
...