Skip to main content

Section 17.2 Objects as Parameters to Methods

The distanceBetween function we just wrote uses a procedural programming approach. In that approach, we solve problems by writing new functions. When we want to know how far apart p1 and p2 are, we write a function and then β€œask” the function β€œhow far is it between p1 and p2?”
However, in an object-oriented design, we would like to encapsulate this functionality within the Point class itself. Other parts of the program shouldn’t be trying to implement basic functionality of a Point like calculating the distance between two of them. That is logic that the Point class programmer is best equipped to implement.
So the object-oriented approach is to have the Point class provide methods to do this work. For the distance example, we would add a method to the Point class that allows us to β€œask” a point p1 β€œhow far is it to point p2?”. We are still going to end up doing the same math to get the answer, but we are now thinking of that math as a job that a Point object does for us instead of a job that we have to do ourselves.
Here is what the code for a Point member function distanceTo might look like (defined outside of the class):
double Point::distanceTo(const Point& other) const {
    double xdiff = other.m_x - m_x;
    double ydiff = other.m_y - m_y;
    double distance = sqrt(xdiff * xdiff + ydiff * ydiff);
    return distance;
}
Key things to note:
  • There is only one parameter to the function, other. This is the other Point object that we want to calculate the distance to. The other point is this - the one that is running the code.
  • We use m_x and m_y to refer to the member variables of the current Point object. This is the β€œthis” object. We also could use getX() and getY().
  • We use other.m_x and other.m_y to refer to the member variables of the other Point object. We also could use other.getX() and other.getY().
  • We say const twice. const Point& other promises not to modify the Point that is passed in as a parameter. The const at the end promises that the object which is executing the code will not be modified.
Something like other.m_x - m_x says β€œsubtract my x value from the other point’s x value.”
To use this function we could write:
int main() {
    Point p1(3.0, 4.0);
    Point p2(6.0, 8.0);
    double distance = p1.distanceTo(p2);
}
When the distanceTo function is executing, we could diagram the memory like this:
When distanceTo is called on p1 and p2 is the parameter, this refers to p1 and other refers to p2
Figure 17.2.1. A memory diagram of p1 executing getX
As before, m_x implicitly means β€œthis object’s m_x”. To specify the other object’s m_x, we need to explicitly specify that we are talking about the other object via other..
You might be surprised to see that p1 can access the private data of p2. This is allowed because they are the same class. Member code of any Point object can access not just its own private data, but also the private data of any other Point. However that would not be the case if a function in a Circle class took a Point as a parameter.
bool Circle::contains(const Point& p) const;
The contains function shown above would not be able to access private data of p. It would need to use public functions getX() and getY() to access p’s coordinates. The function belongs to the Circle class - thus it can only access private data of Circle objects, not Point objects.

Insight 17.2.1.

Access modifiers are designed to protect parts of the code (the Circle class) from other parts of the code (non-Circle code), not to protect individual objects from other objects. That is why they apply to classes of data.

Checkpoint 17.2.1.

Checkpoint 17.2.2.

Checkpoint 17.2.3.

You have attempted of activities on this page.