Skip to content
  • Pass by Value, Reference & Pointer · C++

Pass by Value, Reference & Pointer

LearnViaNotes @learnvianotes· 3 min read

How a parameter is declared decides whether the function gets a copy, an alias to the caller's object, or its address.

The three ways

C++
#include <iostream>

void byValue(int x)      { x = 100; std::cout << "inside " << x << '\n'; }  // a copy
void byReference(int& x) { x = 200; }        // x IS the caller's variable
void byPointer(int* x)   { if (x) *x = 300; } // modifies through the address (may be null)

int main() {
    int a = 1;
    byValue(a);      std::cout << a << '\n';
    byReference(a);  std::cout << a << '\n';
    byPointer(&a);   std::cout << a << '\n';
    byPointer(nullptr);                       // allowed: pointers can express “no object”
}
Output
inside 100
1
200
300
StyleCopies?Can modify caller?Can be null?Use for
T xYesNo—Cheap types (int, double, small structs, iterators), or when you need a copy anyway
const T& xNoNoNoRead-only access to anything non-trivial (std::string, std::vector)
T& xNoYesNoOut/in-out parameters
T* xNoYesYesOptional objects, C APIs
T&& xNoYes (steals)NoTaking ownership of temporaries (move semantics)

Why const& for big objects

C++
#include <iostream>
#include <string>

struct Tracker {
    std::string name;
    Tracker(std::string n) : name(std::move(n)) {}
    Tracker(const Tracker& other) : name(other.name) { std::cout << "copy!\n"; }
};

void slow(Tracker t)        { std::cout << "slow " << t.name << '\n'; }
void fast(const Tracker& t) { std::cout << "fast " << t.name << '\n'; }

int main() {
    Tracker big("report");
    slow(big);      // copies the whole object
    fast(big);      // no copy
}
Output
copy!
slow report
fast report

Swapping — the classic example

C++
#include <iostream>
void swapRef(int& a, int& b) { int t = a; a = b; b = t; }
void swapPtr(int* a, int* b) { int t = *a; *a = *b; *b = t; }
int main() {
    int x = 1, y = 2;
    swapRef(x, y);
    std::cout << x << y << '\n';
    swapPtr(&x, &y);
    std::cout << x << y << '\n';
}
Output
21
12

Passing arrays and containers

C++
#include <iostream>
#include <vector>

int sumArray(const int* arr, std::size_t n) {   // a C array decays to a pointer: size is lost
    int s = 0;
    for (std::size_t i = 0; i < n; ++i) s += arr[i];
    return s;
}
void doubleAll(std::vector<int>& v) { for (int& x : v) x *= 2; }

int main() {
    int raw[] = {1, 2, 3};
    std::cout << sumArray(raw, 3) << '\n';
    std::vector<int> v{1, 2, 3};
    doubleAll(v);
    std::cout << v[0] << v[1] << v[2] << '\n';
}
Output
6
246

Is Java/Python-style pass by reference the same as C++ references?

When would you pass by pointer instead of reference?

Free for students and teachers

Write notes like this one

Cards for every idea, quizzes and flashcards, read aloud — on the web and your phone.

Something wrong with this note? Open it to report