From C to C++
Functions: Overloading, Defaults & Inline
What C++ adds to functions: pass by reference, const references, function overloading, default arguments and inline functions.
Pass by reference
A reference parameter lets a function change the caller's variable — without pointers:
#include <iostream>
using namespace std;
void swapValues(int &a, int &b) { // a and b are aliases for the caller's variables
int t = a;
a = b;
b = t;
}
int main() {
int x = 3, y = 8;
swapValues(x, y); // no & needed at the call
cout << "x = " << x << ", y = " << y << endl;
return 0;
}x = 8, y = 3
Compare the three ways of passing an argument:
| By value | By pointer (C style) | By reference | |
|---|---|---|---|
| Declaration | void f(int a) |
void f(int *a) |
void f(int &a) |
| Call | f(x) |
f(&x) |
f(x) |
| Can change caller's variable | no | yes | yes |
| Copies the argument | yes | no (copies an address) | no |
const references
Passing a large object (like a long string or vector) by value copies the whole thing. Pass it as a const reference instead: no copy, and the function promises not to change it.
#include <iostream>
#include <string>
using namespace std;
int countVowels(const string &s) { // fast and read-only
int n = 0;
for (char c : s)
if (string("aeiouAEIOU").find(c) != string::npos) n++;
return n;
}
int main() {
string text = "Object Oriented Programming";
cout << countVowels(text) << " vowels" << endl;
return 0;
}9 vowels
Function overloading
Several functions can share a name if their parameter lists differ (in number or types). The compiler picks the right one from the arguments — this is compile-time polymorphism.
#include <iostream>
using namespace std;
int area(int side) { return side * side; } // square
int area(int length, int width) { return length * width; } // rectangle
double area(double radius) { return 3.14159 * radius * radius; } // circle
int main() {
cout << "square 4: " << area(4) << endl;
cout << "rectangle 4x6: " << area(4, 6) << endl;
cout << "circle 2.0: " << area(2.0) << endl;
return 0;
}square 4: 16 rectangle 4x6: 24 circle 2.0: 12.5664
Default arguments
Parameters can have default values, used when the caller leaves them out. Defaults must come last in the parameter list:
#include <iostream>
using namespace std;
double simpleInterest(double principal, double rate = 7.5, int years = 1) {
return principal * rate * years / 100;
}
int main() {
cout << simpleInterest(10000) << endl; // rate 7.5, 1 year
cout << simpleInterest(10000, 8) << endl; // 1 year
cout << simpleInterest(10000, 8, 3) << endl;
return 0;
}750 800 2400
Inline functions
inline suggests that the compiler paste the function body at each call, avoiding call overhead for tiny functions. It is a safer replacement for function-like macros because arguments are evaluated once and type-checked:
#include <iostream>
using namespace std;
inline int cube(int x) { return x * x * x; }
#define CUBE(x) x * x * x
int main() {
cout << "inline cube(1 + 2) = " << cube(1 + 2) << endl; // 27
cout << "macro CUBE(1 + 2) = " << CUBE(1 + 2) << endl; // 1 + 2*1 + 2*1 + 2 = 7
return 0;
}inline cube(1 + 2) = 27 macro CUBE(1 + 2) = 7
Modern compilers decide on inlining by themselves, so inline is mostly a hint (and today it matters mainly for functions defined in headers).
Test yourself
4 questions · pick an answer to check it instantly
- 1
Which declaration lets
fchange the caller'sintwithout pointers?A non-const reference parameter aliases the caller's variable. - 2
Which pair is a valid overload?
Overloads must differ in parameter types or count; return type and parameter names do not count. - 3
Which default-argument declaration is valid?
Parameters with defaults must come after all parameters without defaults. - 4
Why pass a large
stringasconst string &?A const reference gives read-only access without the cost of a copy.