If I have two classes: one is Point
and the second is Square
, Point
has member data: x
and y
those are "private" to represent the coordinates of the point.
The class Square
and similar ones implement the "has-a" relationship; so for example Square
has four Points. For some reason Point
grants access to its private data through "friendship"; but only to a member function called print
of the containing classes.
The problem:
The class Point
needs to see the definition of the classes like Square
so that it declares their print member as a friend.
Square
needs to see the definition of class Point
so that it can declare instances of it as its members.
Using forward-declaration won't solve the issue because the fact that it is still "incomplete type". So how it could be solved?
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;
}
}