Skip to content
C++ Better Explained
Go back
C++ const Keyword Explained: Variables, References, and Functions
Edit page

C++ const Keyword Explained: Variables, References, and Functions

The const keyword is one of the simplest features in C++ and one of the most important. It tells the compiler “this value must never change” — and the compiler enforces that promise for you, catching whole categories of bugs before your program even runs.


const variables: values that never change

Declare a variable const and it becomes read-only. You must initialize it immediately, and any later attempt to modify it is a compile error.

#include <iostream>

int main() {
    const double TAX_RATE = 0.08;
    const int MAX_PLAYERS = 4;

    double price = 50.0;
    double total = price * (1 + TAX_RATE);

    std::cout << "Total: " << total << '\n';

    // TAX_RATE = 0.10;  // ERROR: assignment of read-only variable

    return 0;
}

This is better than a “magic number” scattered through your code because the value has a name, lives in one place, and cannot be accidentally overwritten. If you’ve read our guide to variables and data types, think of const as a permanent lock you apply at creation time.


const function parameters: fast AND safe

When you pass a large object like a std::string or std::vector to a function by value, C++ copies the whole thing. Passing by reference avoids the copy — but then the function could modify your original. const reference gives you both benefits:

#include <iostream>
#include <string>

// No copy is made, and the function cannot modify the original
void printGreeting(const std::string& name) {
    std::cout << "Hello, " << name << "!\n";
    // name += "!";  // ERROR: name is read-only here
}

int main() {
    std::string user = "Sahil";
    printGreeting(user);
    return 0;
}

This is efficient because a reference is just an alias for the existing object — nothing gets copied — and it’s safe because the compiler guarantees the function only reads. This pattern is so common it’s the default way to pass strings, vectors, and class objects in C++. For the full picture, see pass by value vs reference.

If you're looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you're a complete beginner or looking to solidify your understanding. Just $19.

const and pointers: two different things to lock

With pointers, const can apply to the data or to the pointer itself. The rule of thumb: read the declaration right to left.

#include <iostream>

int main() {
    int a = 10;
    int b = 20;

    const int* p1 = &a;   // pointer to const int: data is locked
    // *p1 = 99;          // ERROR: can't change the value through p1
    p1 = &b;              // OK: the pointer itself can move

    int* const p2 = &a;   // const pointer to int: pointer is locked
    *p2 = 99;             // OK: can change the value
    // p2 = &b;           // ERROR: can't repoint p2

    std::cout << a << '\n';  // prints 99
    return 0;
}

If pointers are still fuzzy, our beginner’s guide to pointers builds the mental model step by step.


const member functions: methods that promise not to modify

Inside a class, marking a method const promises it won’t change any member variables. Only const methods can be called on a const object, so this matters more than it first appears:

#include <iostream>
#include <string>

class BankAccount {
private:
    std::string owner;
    double balance;

public:
    BankAccount(std::string o, double b) : owner(o), balance(b) {}

    // Promises not to modify the object
    double getBalance() const {
        return balance;
    }

    void deposit(double amount) {
        balance += amount;  // modifies state, so NOT const
    }
};

void printBalance(const BankAccount& account) {
    // Only const methods are callable on a const reference
    std::cout << "Balance: " << account.getBalance() << '\n';
}

int main() {
    BankAccount acct("Sahil", 250.0);
    printBalance(acct);
    return 0;
}

Without const on getBalance(), the call inside printBalance would not compile — the compiler can’t trust a non-const method with a read-only object. New to classes? Start with classes and objects.


const vs constexpr

const means “cannot change after initialization” — but the value can come from runtime input. constexpr is stricter: the value must be computable at compile time.

const int userChoice = getUserInput();   // OK: fixed after runtime init
constexpr int BOARD_SIZE = 8 * 8;        // OK: known at compile time

Use constexpr for true constants like array sizes and mathematical values, and const everywhere you want to lock a value after it’s computed.



Take Your C++ Further

If you’re looking to go deeper with C++, the C++ Better Explained Ebook is perfect for you — whether you’re a complete beginner or looking to solidify your understanding. Just $19.

👉 Get the C++ Better Explained Ebook — $19

📋

Free Download: The 10 Mistakes Every C++ Beginner Makes

A free 1-page checklist that shows the exact traps that slow down every C++ beginner — so you can avoid them from day one.

🔒 No spam. Unsubscribe anytime.


Edit page
Share this post on:

Previous Post
How to Compare Strings in C++: ==, compare(), and strcmp Explained
Next Post
C++ Number Guessing Game: A Complete Beginner Project Step by Step