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: