C++
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Object-Oriented C++
-
Section 4: Memory Management
-
Section 5: Templates and Generic Programming
-
Section 6: The Standard Template Library
-
Section 7: Modern C++ Features
-
Section 8: Error Handling
-
Section 9: Multithreading
-
Section 10: Operator Overloading and Type Conversion
-
Section 11: Advanced Topics
-
Section 12: Tooling and Build Systems
-
Section 13: Design Patterns in C++
-
Section 14: Interfacing with C and Systems Programming
-
Section 15: Networking and IPC Basics
-
Section 16: Graphics and Game Programming Basics
-
Section 17: The Boost Libraries
-
Section 18: Data Structures and Algorithms in C++
-
Section 19: Practical Projects
-
Section 20: More Concurrency Patterns
-
Section 21: More OOP and Design Practice
-
Section 22: File I/O and Streams
-
Section 23: More Standard Library
-
Section 24: Practice Exercises
-
Section 25: Interview and Algorithm Practice
-
Section 26: Compiler and Language Internals
-
Section 27: GUI and Application Frameworks Overview
-
Section 28: Testing and Quality Practices
-
Section 29: Numerics Library
-
Section 30: Concepts Library (C++20)
-
Section 31: Ranges Library (C++20) In Depth
-
Section 32: More Utility Library
44: Pointers and References Revisited
By this point in the course, you've used pointers and references plenty of times. But I've noticed that even experienced devs sometimes hesitate when deciding which one to use in a new function. Itβs easy to memorize the syntax, but harder to internalize the intent. Let's clear that up.
Think of it like this: Imagine you have a physical house. A pointer is like a scrap of paper with the house's address written on it. You can pass that piece of paper to anyone. You can erase the address and write a different one on it. You can even have a blank piece of paper (a nullptr) that doesn't point to any house at all. A reference, on the other hand, is like a nickname for the house. If you call it "The Old Manor," that name is permanently glued to that specific building. You can't suddenly decide that "The Old Manor" now refers to the cottage down the street.
The Flexibility of the Address Slip
Because a pointer is just a variable holding an address, it's incredibly flexible. You can change what it points to on the fly. I use this all the time when I'm implementing data structures like linked lists or trees where the "current" node needs to shift constantly.
int score1 = 10;
int score2 = 20;
int* currentScore = &score1; // The paper says "House 1"
// Now I want to track the second score
currentScore = &score2; // I erased House 1 and wrote "House 2"
Notice that currentScore itself changed. We didn't change the value of the scores; we changed which score we were looking at. That's the core power of the pointer.
The Permanence of the Nickname
References are different. When you initialize a reference, you're not creating a new "object" in the way a pointer is; you're creating an alias. Once ref is bound to var, it is var for the rest of its life. If you try to "reassign" a reference, you're actually just changing the value of the original variable.
int health = 100;
int backupHealth = 50;
int& healthRef = health; // "healthRef" is now just another name for "health"
healthRef = backupHealth; // This does NOT make healthRef point to backupHealth.
// Instead, it changes the value of 'health' to 50.
This is where people usually get tripped up. If you're expecting the reference to jump to a new variable, you're in for a surprise. It's anchored. This makes references much safer and cleaner for function parameters because you don't have to worry about the reference suddenly pointing to something else mid-function.
Handling the "Empty" Case
One of the biggest deciding factors for me is whether "nothing" is a valid option. A reference must refer to something. You can't have a null reference (well, you can technically force one with some very bad hacks, but please don't). If your logic allows for the possibility that an object might not exist, you have to use a pointer.
I often use this when dealing with optional components in a game engine. For example, a Character might have a Weapon* currentWeapon. If the character is unarmed, currentWeapon is simply nullptr. If I used a reference, I'd be forced to create a "FakeWeapon" object just to satisfy the compiler, which is a messy waste of memory.
Choosing Your Tool
So, how do I decide in the heat of the moment? I follow a simple hierarchy of preference:
- Use a reference by default for function parameters. It tells the caller, "I need an actual object to work with, and I'm not going to change which object I'm talking about."
- Use a pointer if you need to be able to reassign the target or if "null" is a meaningful state in your logic.
- Use a const reference (
const T&) if you want the efficiency of not copying a large object, but you want to guarantee you won't accidentally modify it.
π Practical Task
Building a Dynamic Equipment Linkage System
You are tasked with creating a simplified equipment system for an RPG. The goal is to demonstrate the correct use of pointers for optional items and references for core attributes.
Requirements:
- Create a
Statclass that holds a single integer value (e.g.,strength). - Create an
Itemclass that holds a name (string) and a strength bonus (integer). - Create a
Characterclass with:- A
Statobject calledbaseStrength. - A pointer to an
ItemcalledequippedWeapon(this should be initialized tonullptr).
- A
- Implement a function
void calculateTotalStrength(const Character& c, int& total). This function must use a reference for the Character to avoid copying, and a reference for the total to return the calculated value. - The logic for
calculateTotalStrengthshould be:- Start with the character's
baseStrength. - Check if
equippedWeaponis not null. If it exists, add the weapon's bonus to the total.
- Start with the character's
Your task: Write the full implementation. In your main function, create a character, calculate their strength while unarmed, then equip a weapon (by assigning its address to the pointer) and calculate the strength again to verify the increase.
There are no comments for now.