# Passing Object Parameters

#### Passing Object Parameters

``````void print_fraction(SimpleRational f)
{
std::cout << f.get_numerator() << "/" << f.get_denominator();
}``````

Observe that the function accepts its parameter f using the call by value protocol.

``````SimpleRational my_rational{3, 4};
print_fraction(my_rational);``````
``````void print_fraction(const SimpleRational& f)
{
std::cout << f.get_numerator() << "/" << f.get_denominator();
}``````
``````// Returns the product of two rational numbers
SimpleRational multiply(const SimpleRational& f1,
const SimpleRational& f2)
{
return {f1.get_numerator() * f2.get_numerator(),
f1.get_denominator() * f2.get_denominator()};
}``````

If passing object types by const reference for object types is the better approach why does C++ not do this automatically for us? C++ defaults to pass by value as the default. This guarantees safety for all types at the expense of reduced efficiency for some types.

``````SimpleRational zero1(const SimpleRational & f) {
SimpleRational result {
f
}; // Make a copy of parameter f
result.set_numerator(0);
return result;
}``````
``````SimpleRational zero2(SimpleRational f) {
// Just use f; it is a copy of the caller's actual parameter
f.set_numerator(0);
return f;
}``````

A caller could use the zero1 and zero2 functions as shown here:

``````SimpleRational one_third{1, 3};
auto other = zero1(one_third);
// Caller owns two objects: one_third (1/3) and other (0/3).``````

#### Pointers to Objects and Object Arrays

``Point pt;``

declares the variable pt to be a Point object. As with primitive data, we can declare pointers to objects:

``````Point pt;
Point *p_pt;``````

Here, p_pt is a pointer to a Point object. We can assign the pointer to refer to an existing object, as in

``p_pt = &pt;``

or use the new operator to dynamically allocate an object from the heap:

``p_pt = new Point;``

Recall the Account class from Given the declarations

``````Account acct("Joe", 3143, 90.00);
Account *acct_ptr;``````

or use the new operator to dynamically allocate an object from the heap:

``acct_ptr = new Account("Moe", 400, 1300.00);``
``*(p.x) = 253.7; // Error``
``````Point *p = new Point;
p->x = 253.7;
p->y = -00.5;``````

The pair of symbols -> constitute one operator (no space in between is allowed), and the operator is meant to look like an arrow pointing right. There is no associated left pointing arrow in C++.

``````Account *acct_ptr = new Account("Joe", 400, 1300.00);
if (acct_ptr->withdraw(10.00))
std::cout << "Withdrawal successful\n";
else
std::cout << "*** Insufficient funds ***\n"``````

It represents a simple address, essentially a number. The problem is acct_ ptr points to memory that was allocated with new, and this memory is not freed up within the function.

``````void corrected_func() {
Account * acct_ptr = new Account("Joe", 400, 1300.00);
if (acct_ptr - > withdraw(10.00))
std::cout << "Withdrawal successful\n";
else
std::cout << "*** Insufficient funds ***\n";
acct_ptr - > display();
delete acct_ptr;
}``````

C++ supports vectors and arrays of objects, but they present special challenges. First, consider a simple situation. The Point class defines no constructor, so the following code is valid: