CodeRef
CodeRef
  • Software
    • VSCode
  • Midjourney_AI
    • Midjourney Cheat Sheet
  • aws
    • S3 Reference
    • Services
  • bash
    • .bashrc File Contents
    • CAN
    • _System Config File Locations
    • argument-length-limits
    • Conditionals
    • Data Structures
    • File Permissions
    • File Syncing
    • File System
    • Functions
    • General
    • Loops
    • My Functions
    • Networking
    • Number Operations
    • OpenVPN
    • Operators
    • Resource Management
    • Serial RS232
    • Spinning Wheel Animation
    • SSH
    • Text Operations
    • Environment Variables
  • cpp
    • ChatGPT | Pointers vs. References
    • arrays
    • Classes
    • Data Types / Structures
    • Enumerated Classes
    • Exception Handling
    • Function Objects
    • Functions
    • I/O
    • Loops
    • Macros
    • Namespaces
    • New Features
    • Pointers
    • Scope
    • Smart Pointers
    • Raw String Literals
    • Style Guide
    • Switch Case
    • Templating
    • How to Use tinyxml2
    • Useful Libraries
    • google-test
    • Conditionals
    • Rule of Three/Five
    • Optional Parameters
    • Keywords
    • Filesystem
    • Random
    • Casting
    • tools
  • git
    • Code Review Dependency Strategy
    • Git Bisect Guide
    • Git Reference
    • removing-cherry-picks
    • Useful Tools
    • Graphite Reference
  • js
    • functions
    • Javascript Reference
  • linux
    • Display
    • Dual Boot with Windows
    • File System
    • NVIDIA
    • Sending/Receiving TCP/UDP Messages in Ubuntu
    • dynamically_linked_binaries
  • markdown
    • Images
    • obsidian-reference
  • python
    • Classes
    • Exceptions
    • Functions
    • Operations
    • Python Reference
    • unittest_command-line-args
    • unittest_magicmock_GPT
    • unittest_mock
    • unittest_printing
    • unittest_subtest
    • useful-stuff
    • jupyter
    • poetry
  • ros
    • _ROS Cheat Sheet
    • Create New Workspace
    • Install ROS
    • Node Sample - Listener
    • Node Sample - Talker
    • Node Template
    • Setup
    • urdf
  • excel
    • excel-reference
  • windows
    • File System
    • WSL - Windows Subsystem for Linux
    • WSL
  • software_engineering
    • uncle_bob_lectures
      • Overview
      • Lesson 01 - Notes
  • web
    • Front End
    • Hugo
    • new_frontend_tools
  • sql
    • cheatsheet
Powered by GitBook
On this page
  1. cpp

ChatGPT | Pointers vs. References

Pointers and references are both used for indirect access to data in C++, but they have key differences in how they work:

  1. Pointers (int*):

    • Pointers are variables that store memory addresses.

    • They provide a level of indirection, allowing you to indirectly access data at a specific memory location.

    • Pointers can be reseated (pointed to different memory locations) or set to nullptr.

    • You need to use the dereference operator (*) to access the data pointed to by the pointer.

    • Pointers can be used for various types of dynamic memory management.

    Example:

    int x = 42;
    int* ptr = &x; // Pointer to an integer.
    int value = *ptr; // Accessing data through the pointer.
  2. References (int&):

    • References are aliases to existing variables.

    • They provide a way to directly access data without involving memory addresses or pointers.

    • References cannot be reseated; once bound to a variable, they always refer to that variable.

    • References are often used for function parameters to pass data efficiently and without copying.

    • They are syntactically simpler than pointers and do not require explicit dereferencing.

    Example:

    int x = 42;
    int& ref = x; // Reference to an integer.
    int value = ref; // Direct access through the reference.

In summary, the main differences between pointers and references are reseatability (pointers can be reseated, references cannot), syntax (pointers require dereferencing with *, references do not), and the level of indirection (pointers involve memory addresses, while references are direct aliases to variables).

Both pointers and references have their use cases. Pointers are suitable for more complex memory management scenarios and situations where reseating is needed, while references provide a simple and efficient means of working with existing data.

Here are some examples of using references in C++:

  1. Function Parameters: You can use references as function parameters to pass data efficiently without making a copy. This is commonly used for functions that need to modify the passed data.

    void increment(int& num) {
        num++;
    }
    
    int main() {
        int value = 5;
        increment(value); // Pass 'value' by reference.
        std::cout << value; // Outputs 6
        return 0;
    }
  2. Range-Based For Loop: You can use references in a range-based for loop to iterate over elements of a container without copying the elements.

    std::vector<int> numbers = {1, 2, 3, 4, 5};
    for (int& num : numbers) {
        num *= 2; // Modify each element directly.
    }
  3. Returning Values: You can return values by reference from a function, which allows you to modify the original data.

    // You can pass in a std::vector<int>, it doesn't
    // need to be a reference of one, but it can be. The function
    // will automatically create a reference to it if it's
    // not already a reference.
    int& getFirst(std::vector<int>& vec) {
        // A regular integer is being returned,
        // not a reference to an integer.
        // This works because the vector object
        // exists and persists outside the function's
        // scope, so vec[0] does as well.
        // The receiving variable must be an int&.
        return vec[0];
    }
    
    int main() {
        std::vector<int> numbers = {1, 2, 3};
        int& first = getFirst(numbers);
        first = 42; // Modifies the first element in 'numbers'.
    }
  4. Avoiding Copying Large Objects: When working with large objects, using references can help avoid the overhead of copying.

    struct LargeObject {
        // ...
    };
    
    void processLargeObject(const LargeObject& obj) {
        // Process 'obj' without making a copy.
    }

References are particularly useful when you want to modify data within functions or avoid the cost of copying large objects. They provide a way to work with data more efficiently and directly.

More Examples of References and Functions

(I write this part).

This code is invalid and will lead to undefined behavior. This will pass "p" to the function by reference. "2*input" will create a temporary variable of value of 6, which must only be returned as a copy. "x" is trying to receive it as a reference. You can't receive a reference to a temporary variable because the temp variable will be deleted when the function exits. Thus, this will lead to undefined behavior. "p" will still have the value 3 at the end.

int& func(int& input) {
	return 2*input; // Temporary varable created = 6.
}
int p = 3;
int& x = func(p);

This will solve the problem by "x" receiving the return value by copy, not by reference.

int& func(int& input) {
	return 2*input; // Temporary varable created = 6.
}
int p = 3;
int x = func(p);

This will also solve the problem. By first updating the variable "input" in the function before returning it, the variable receiving the function return can now receive a reference. Note that this only works if a variable is passed to the function input, not a raw value (like 3). In this case, both "p" and "x" will have value 6 at the end.

int& func(int& input) {
	input = 2*input;
	return input;
}
int p = 3;
int& x = func(p);

This will not work. When passing the raw value 3 to the function, it will create a temporary variable and pass its reference into the function. You will calculate a result of 6, but you can't return it by reference because the temporary object is destroyed when the function exits.

int& func(int& input) {
	return 2*input; // Temporary varable created = 6.
}
int& x = func(3);

This will not work. "temp" is scoped within the function, so its reference can't be returned.

int& func(int& input) {
	int temp = 2*input;
	return temp;
}
int p = 3;
int& x = func(p);

If you want to have a function modify an existing data object, do this:

void func(int& input) {
	input = // modifications
}

This also works if you want to have another reference to the original object. This could be useful if you pass a regular variable into the function and not a reference to one.

int& func(int& input) {
	input = // modifications
	return input;
}

Last updated 1 year ago