I don't see how this breaks encapsulation; you're the one designing the intricacies of the class. You would have to know what's internally in the class to make any sense of a constructor, whether a "normal" constructor or a copy constructor.
Does this break encapsulation?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
class Point {
public:
Point(double x, double y)
{
this->radius_squared = x*x + y*y;
this->theta = atan2(y, x);
}
Point(const Point& other)
{
this->radius_squared = other.radius_squared;
this->theta = other.theta;
}
double getX() {
return sqrt(radius_squared) * cos(theta);
}
double getY() {
return sqrt(radius_squared) * sin(theta);
}
private:
double radius_squared;
double theta;
};
|
I wouldn't say so. You, in order to make the constructor, have to know that internally it's the radius squared being stored. What makes the 2-arg constructor any better than the copy constructor, according to this logic? This isn't the most realistic or efficient example... but I think it shows the basic concept. The user doesn't know what the internal representation of the x and y are, and the user doesn't
need to know that. But you, as the class designer, have to either way.
The
user of the class still doesn't have to know about the inner details.
1 2 3 4 5 6 7 8
|
int main()
{
Point point(3, 2); // normal constructor
Point origin(0, 0);
Point p3(point); // encapsulation is not being broken here anymore than above
cout << p3.getX() << endl;
}
|
btw, point classes are sometimes simple enough such that the class designers just keep the x and y member variables public, such as in SFML. If the class is simple enough and is meant to just "hold data" instead of being a functional, independent object, then this can be okay.