As we start implementing getters for our Circle, we might decide we want a getCenter() in addition to getX() and getY(). If a client of the class wants to know where a circle is, asking for the center Point is easier than asking for the x and y values separately. But this raises an important question: what should the getCenter() return?
Point Circle::getCenter() const {
return m_center;
}
Any time we return an object type like that, we are returning a copy of the center point. This means that doing Point p2 = c1.getCenter() would produce a brand new Point that just copied the data from c1βs center:
This is the easiest thing to do. And, in many ways the safest. By giving the client a copy of its center, the Circle does not need to worry about what happens to the Point.
We will generally use that easy approach. The rest of this section focuses on improvements that would only be worth making in a program that worked with lots of data or to solve complex design problems. Mastering these concepts should be a lower priority than mastering the rest of the chapter.
However, the easy approach is not always the best approach. Firstly, it involves copying the Point. This is not a big deal for a small class like Point that we only copy a few (or even a few hundred) times. But if we were to copy a large object, or make millions of copies of small ones, the expense would become something to be concerned about. Secondly, we might want to allow the client to use the Point we give them to change the center of the circle.
Now, we are returning a reference to the actual m_center object. If the client stores the returned value as a reference (Point& p3 = c1.getCenter();) it has a link to the Point object that is actually the center of c1:
In this case, p3.setY(10) would actually change the m_y of the m_center of c1 as p3 is just another name for c1.m_center. Because the reference can be used to modify the Point (and thus the Circleβs data), this version of getCenter is not (and can not be) const.
If the client wants, it could store the value into a plain Point variable with Point p4 = c1.getCenter();. In this case, we are taking the reference, and copying it into the new p4. The reference is then discarded. So we end up with a memory diagram that looks just like FigureΒ 17.10.1.
What if we want to return a reference to a Point but we donβt want the client to be able to modify it? We could do this by returning a const reference. This would look like:
What a mouthful. Circle::getCenter() const is a const function (it will not allow changes to the Circle or its data). It returns (const Point &) a reference to a Point that is constant.
The const on the return type says that the reference we return can not be used to make changes to the Point. To honor that requirement, client code would need to store the returned value into a const reference: const Point& p5 = c1.getCenter();. The memory diagram would look just like the normal reference version (FigureΒ 17.10.2), but p5 could only be used to access const members of the Point class like getX(). We could not use it to do anything that would change the Point.