4.0 What This Teaches
- Defining functions and declaring return types
- Default arguments
- Function overloading - same name, different parameter types
- Pass by value, by reference, and by const reference
- Returning values and returning by reference
4.1 Defining a Function
int add(int a, int b) {
return a + b;
}
main with a forward declaration at the top:
int add(int a, int b); // forward declaration
int main() {
std::cout << add(3, 4) << "\n";
}
int add(int a, int b) { return a + b; }
4.2 Default Arguments
double circle_area(double radius, double pi = 3.14159265) {
return pi * radius * radius;
}
circle_area(5.0); // uses default pi
circle_area(5.0, 3.14159265); // explicit pi
4.3 Function Overloading
void print_value(int x) { std::cout << "int: " << x << "\n"; }
void print_value(double x) { std::cout << "double: " << x << "\n"; }
void print_value(std::string s) { std::cout << "string: " << s << "\n"; }
4.4 Pass by Value, Reference, and Const Reference
// pass by value: caller's copy is unchanged
void double_it(int x) { x *= 2; }
// pass by reference: caller's variable is modified
void double_in_place(int& x) { x *= 2; }
// pass by const reference: no copy, no modification (best for large types)
void print_string(const std::string& s) { std::cout << s << "\n"; }
std::string, std::vector,
structs) by const& to avoid copying. Pass small types
(int, double, pointers) by value.
4.5 Returning Values
std::string make_greeting(const std::string& name) {
return "Hello, " + name + "!";
}
// return type void: no return value
void greet(const std::string& name) {
std::cout << make_greeting(name) << "\n";
}
4.6 Example - All Together
// Functions - definitions, overloading, default args, and pass by reference.
#include <iostream>
#include <string>
#include <cmath>
int add(int a, int b) { return a + b; }
double circle_area(double radius, double pi = 3.14159265) {
return pi * radius * radius;
}
void print_value(int x) { std::cout << "int: " << x << "\n"; }
void print_value(double x) { std::cout << "double: " << x << "\n"; }
void print_value(std::string s) { std::cout << "string: " << s << "\n"; }
void swap_values(int& a, int& b) {
int tmp = a; a = b; b = tmp;
}
int main() {
std::cout << "add(3,4) = " << add(3, 4) << "\n";
std::cout << "circle_area(5) = " << circle_area(5.0) << "\n";
print_value(42);
print_value(3.14);
print_value(std::string("hello"));
int x = 10, y = 20;
swap_values(x, y);
std::cout << "after swap: x=" << x << " y=" << y << "\n";
return 0;
}
add(3,4) = 7
circle_area(5) = 78.5398
int: 42
double: 3.14
string: hello
after swap: x=20 y=10
4.7 Exercise
Exercise
- Write an overloaded
max_offunction that works forint,double, andstd::string. - Write a function
clamp(int value, int lo, int hi)that returnsvalueclamped to the inclusive range[lo, hi]. - Write a function that takes a
std::string&by reference and converts it to uppercase in place usingstd::toupperon each character.
4.8 Common Mistakes
Expecting pass-by-value to modify the caller's variable
void increment(int x) { x++; } // modifies a copy, not the caller's variable
int n = 5;
increment(n);
std::cout << n; // still 5
int& x to modify the caller's variable.Returning a reference to a local variable
int& bad() {
int local = 42;
return local; // dangling reference: local is destroyed on return
}
Ambiguous overloads
void f(int x) {}
void f(double x) {}
f(3.0f); // error: ambiguous - float converts equally well to int or double
float or cast the argument explicitly.4.9 Key Terms
| Term | Meaning |
|---|---|
| forward declaration | Declares a function's signature without its body; allows calling it before its definition |
| default argument | A parameter value used when the caller does not supply one |
| overloading | Multiple functions with the same name but different parameter types |
| pass by value | Caller's argument is copied; changes do not affect the caller |
| pass by reference (&) | Function operates on the caller's variable directly |
| pass by const reference | No copy, no modification; best for large types |
| RVO | Return Value Optimization: compiler elides the copy when returning a local object |