Home

Details on Passing Arguments

 

Function Overloading

We saw earlier that, when declaring a function, the compiler needs to know only the name of the function, its return type and its type(s) of argument(s), if any.  We also saw that a function could be declared as follows:

float Area(float, float);

The name of a function, its return type, and its list of arguments, if any, constitute the function's signature. This signature gives complete information to the compiler regarding each function. The compiler needs this information about each function because it creates a table (called a virtual table) of all functions used in a particular file whether it is a header file or a source file. When creating this table, the compiler assigns a unique identification (like somebody's driver's license) to each function, using the function's name, its return type, and its argument(s) (this allows the compiler to perform name mangling).

When creating this table, the compiler uses each function's name and its argument(s), if any:

  • If two functions have different names, they would have different identifications, regardless of their argument(s), if any
  • If two functions have the exact same name and exact same type(s) or argument(s), both functions would have the same identification, which would result into a conflict (of course, you can use namespaces to prevent this conflict)
  • If two functions have the exact same name but different argument(s), either by the number of arguments or the type(s) of argument(s), they would have different identifications. 

The ability for two functions to have the exact same name but differ either by their type(s) of argument(s) or by their number of argument(s) allows the compiler to distinguish them. This is the foundation of Function Overloading: Function Overloading is the ability to have various functions that have the same name but different arguments, either by the number of arguments of each function or by the types of arguments of each function.

Here is an example:

using namespace System;

// Area of a square
float Area(float Side)
{
    return (Side * Side);
}

// Area of a rectangle
float Area(float Length, float Width)
{
    return (Length * Width);
}

int main()
{
    float s, l, w;

    s = 15.25f;
    l = 28.12f;
    w = 10.35f;

    Console::WriteLine("The area of the square is {0}", Area(s));
    Console::WriteLine("\nThe area of the rectangle is {0}", Area(l, w));
    
    return 0;
}

Here is the result of running the program:

The rea of the square is 232.562
The area of the rectangle is 291.042

Press any key to continue...

You can also declare overloaded functions as inline and/or.

Default Arguments

Whenever a function takes an argument, that argument is required. If the calling function doesn't provide the (required) argument, the compiler would throw an error. Imagine you write a function that will be used to calculate the final price of an item after discount. The function would need the discount rate in order to perform the calculation. Such a function could look like this:

double CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

Since this function expects an argument, if you do not supply it, the following program would not compile:

using namespace System;

double CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

int main()
{
    double FinalPrice;
    double Discount = 15; // That is 25% = 25

    FinalPrice = CalculateNetPrice(Discount);

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

Here is an example of running the program:

Please enter the original price: 250.50

After applying the discount
Final Price = 212.925
Press any key to continue . . .

Most of the time, a function such as this CalculateNetPrice() would use the same discount rate over and over again. Therefore, instead of supplying an argument all the time, C++ allows you to define an argument whose value would be used whenever the function is not provided with a value for the argument.

To give a default value to an argument, when declaring the function, type the name of the argument followed by the assignment operator, =, followed by the default value. The CalculateNetPrice() function, with a default value, could be defined as:

using namespace System;

double CalculateNetPrice(double DiscountRate = 20);

int main()
{
    double FinalPrice;

    FinalPrice = CalculateNetPrice();

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

double   CalculateNetPrice(double DiscountRate)
{
    double OrigPrice;

    Console::Write("Please enter the original price: ");
    OrigPrice = double::Parse(Console::ReadLine());

    return OrigPrice - (OrigPrice * DiscountRate / 100);
}

Here is an example of running the program:

Please enter the original price: 120.15

After applying the discount
Final Price = 90.1125

Press any key to continue...

If a function takes more than one argument, you can provide a default argument for each and select which ones would have default values. If you want all arguments to have default values, when defining the function, type each name followed by = and followed by the desired value. Here is an example:

using namespace System;

double CalculateNetPrice(double Tax = 5.75, double Discount = 25,
                         double OrigPrice = 245.55);

int main()
{
    double FinalPrice;

    FinalPrice = CalculateNetPrice();

    Console::WriteLine("\nAfter applying the discount");
    Console::WriteLine("Final Price = {0}", FinalPrice);
    
    return 0;
}

double CalculateNetPrice(double Tax, double Discount, double OrigPrice)
{
    double DiscountValue = OrigPrice * Discount / 100;
    double TaxValue = Tax / 100;
    double NetPrice = OrigPrice - DiscountValue + TaxValue;

    Console::WriteLine("Original Price: {0:C}", OrigPrice);
    Console::WriteLine("Discount Rate:  {0:P}", Discount/100);
    Console::WriteLine("Tax Amount:     {0:C}", Tax);

    return NetPrice;
}

Here is the result produced:

Original Price: $245.55
Discount Rate:  25.00 %
Tax Amount:     $5.75

After applying the discount
Final Price = 184.22
Press any key to continue . . .

If a function takes more than one parameter and you would like to provide default values for those parameters, the order of appearance of the arguments is very important.

  1. If a function takes two parameters, you can declare it with default values. We already know how to do that. If you want to provide a default value for only one of the arguments, the argument that would have a default value must be the second in the list. Here is an example:
    double CalculatePrice(double Tax, double Discount = 25);

    When calling such a function, if you supply only one argument, the compiler would assign its value to the first parameter in the list and ignore assigning a value to the second:

    using namespace System;
    
    double CalculateNetPrice(double Tax, double Discount = 25);
    
    int main()
    {
        double FinalPrice;
        double TaxRate = 5.50; // = 5.50%
    
        FinalPrice = CalculateNetPrice(TaxRate);
    
        Console::WriteLine("\nAfter applying a 25% discount and a 5.50% tax rate");
        Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
        
        return 0;
    }
    
    double CalculateNetPrice(double Tax, double Discount)
    {
        double OrigPrice, DiscountValue, TaxValue, NetPrice;
    
        Console::Write("Enter the original price of the item: ");
        OrigPrice = double::Parse(Console::ReadLine());
    
        DiscountValue = OrigPrice * Discount / 100;
        TaxValue = Tax / 100;
        NetPrice = OrigPrice - DiscountValue + TaxValue;
    
        return NetPrice;
    }

    Here is an example of running the program:

    Enter the original price of the item: 250.50
    
    After applying a 25% discount and a 5.50% tax rate
    Final Price = 187.93
    
    Press any key to continue...

    If you define the function and assign a default value to the first argument, if you provide only one argument when calling the function, you would receive an error.

  2. If the function receives more than two arguments and you would like only some of those arguments to have default values, the arguments that would have default values must be at the end of the list. Regardless of how many arguments would or would not have default values, start the list of arguments without those that would not use default values. Here is an example: 

    using namespace System;
    
    double RequestOriginalPrice();
    double CalculateNetPrice(double Price, double Tax = 5.75,
                                        double Discount = 25);
    
    int main()
    {
        double OriginalPrice, FinalPrice;
    
        OriginalPrice = RequestOriginalPrice();
        FinalPrice    = CalculateNetPrice(OriginalPrice);
    
        Console::WriteLine("\nAfter applying a 25% discount and a 5.75% tax rate");
        Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
        
        return 0;
    }
    
    double RequestOriginalPrice()
    {
        double OrigPrice;
    
        Console::Write("Enter the original price of the item: ");
        OrigPrice = double::Parse(Console::ReadLine());
        return OrigPrice;
    }
    
    double CalculateNetPrice(double Price, double Tax,
                                         double Discount)
    {
        double DiscountValue, TaxValue, NetPrice;
    
        DiscountValue = Price * Discount / 100;
        TaxValue = Tax / 100;
        NetPrice = Price - DiscountValue + TaxValue;
    
        return NetPrice;
    }

    Here is an example of running the program:

    Enter the original price of the item: 250.50
    
    After applying a 25% discount and a 5.75% tax rate
    Final Price = 187.933
    
    Press any key to continue...

    As you can see, the argument(s) that has(have) default value(s) must be last in the list of arguments.

Constant Arguments

When a function receives an argument, it behaves in one of two manners with regards to the value of the argument; it might modify the value itself or only use the argument to modify another argument or another of its own variables. If you know that a function should not alter the value of an argument, you should let the compiler know. The compiler will make sure that the argument supplied stays intact; if the function tries to modify the argument, the compiler would throw an error, letting you know that an undesired operation took place. Also, this speeds up execution.

To let the compiler know that the value of an argument must stay constant, use the const keyword before the data type of the argument. The double CalculateDiscount() function above receives two arguments, the marked price of an item and the discount rate applied on it. This function uses the two values to calculate the amount of discount that a customer would receive. Since the marked price is set on the item in the store, the function does not modify its value; it only needs it in order to calculate the new price so the customer can see the difference. The function then returns the discount amount. To reinforce this fact and to prevent the CalculateDiscount() function from changing the value of the marked price, you can declare the argument as constant:

double CalculateNetPrice(const double Price, double Tax = 5.75,
                                    double Discount = 25);

If you declare a function before implementing it, make sure you specify the argument as constant in both cases:

using namespace System;

double RequestOriginalPrice();
double CalculateNetPrice(const double Price, double Tax = 5.75,
                                    double Discount = 25);

int main()
{
    double OriginalPrice, FinalPrice;

    OriginalPrice = RequestOriginalPrice();
    FinalPrice = CalculateNetPrice(OriginalPrice);

    Console::WriteLine("\nAfter applying a 25% discount and a 5.75% tax rate");
    Console::WriteLine("Final Price = {0:C}\n", FinalPrice);
    
    return 0;
}

double RequestOriginalPrice()
{
    double OrigPrice;

    Console::Write("Enter the original price of the item: ");
    OrigPrice = double::Parse(Console::ReadLine());
    return OrigPrice;
}

double CalculateNetPrice(const double Price, double Tax,
                                     double Discount)
{
    double DiscountValue, TaxValue, NetPrice;

    DiscountValue = Price * Discount / 100;
    TaxValue = Tax / 100;
    NetPrice = Price - DiscountValue + TaxValue;

    return NetPrice;
}

Once again, only the signature of the function is important. If you are simply declaring the function, the name of the argument is not important, neither is its presence. Therefore, the above CalculateDiscount() function can as well be declared as follows:

double CalculateNetPrice(const double, double = 5.75,
                                    double = 25);

You can pass just one argument as constant. You can almost pass a few or all arguments as constants. It depends on the role of the arguments in the implementation of the function.

 

Previous Copyright © 2006 FunctionX, Inc. Next