Functions in C++

Introduction

Functions let you name a piece of work, test it alone and use it again. C++ adds two conveniences to the basic idea: default values for parameters, and the ability to use one name for several related functions.

How it works

A function has a return type, a name and parameters. void means that it returns nothing. Parameters are copies by default, so changing one inside a function does not affect the caller. The next lesson shows how to change that.

Declaring first. The compiler reads the file from the top, so a function must be defined, or at least declared, before it is called.

Default arguments fill in what the caller leaves out. They must come last in the parameter list, because arguments are matched from the left.

Overloading means giving several functions the same name, as long as their parameter types or counts differ. The compiler picks the right one from the arguments:

#include <iostream>
#include <string>
using namespace std;

int twice(int x) {
    return x * 2;
}

string twice(string s) {
    return s + s;
}

int main() {
    cout << twice(21) << endl;
    cout << twice(string("ab")) << endl;
    return 0;
}
Open in compiler

The string(...) is needed because a piece of quoted text is not yet a string.

Overloads cannot differ only in their return type, because a call does not say which return type it expects.

Syntax

int square(int x);                 // declaration

double area(double w, double h = 1.0) {
    return w * h;
}

int square(int x) {
    return x * x;
}

Example

#include <iostream>
using namespace std;

double area(double w, double h = 1.0) {
    return w * h;
}

int main() {
    cout << area(3.5, 2) << endl;
    cout << area(4) << endl;
    return 0;
}
Open in compiler

Line by line

  1. area has two parameters, and the second has a default of 1.0.
  2. area(3.5, 2) gives both, so the result is 7.
  3. area(4) leaves out h, so the default is used.
  4. Each result is printed on its own line.

Expected result

7
4

In the real world

The standard library uses overloading everywhere. cout << is overloaded for every printable type, which is why one operator can print anything. Default arguments keep common calls short.

Common mistakes

  • Calling a function before it is declared.
  • Forgetting return in a function that should return a value.
  • Putting a default before a parameter without one.
  • Expecting a function to change the caller's variable through a normal parameter.

Best practices

  • Give each function one job, and a name that describes it.
  • Return results, and let the caller decide whether to print them.
  • Use overloads only when the functions really do the same thing.

Summary

Functions take copies of their arguments and can return a value. Default arguments make trailing parameters optional. Overloading lets one name serve several parameter types.

Quick check

1. double f(double a, double b = 2); What is f(3) if it returns a * b?
2. Which declaration is not allowed?
3. Two overloads differ only in their return type. What happens?
4. What does a void function return?

Key takeaways

  • A function must be declared before it is called.
  • Default arguments go at the end of the parameter list.
  • Overloads differ in their parameters, not only in their return type.

Practice problems for this lesson

My notes

Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.