Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The * symbol in C++ is a context-dependent token that functions mechanically as a type modifier for pointer declarations, a unary indirection (dereference) operator, and a binary arithmetic multiplication operator. The compiler determines its semantic meaning based strictly on its syntactic placement within a statement or expression.

1. Pointer Declaration (Type Modifier)

In a declaration context, * acts as a type modifier. It modifies a base type specifier to create a compound type representing a memory address. Syntactically, the * is part of the declarator (which includes the identifier along with pointer operators, array bounds, or function parameters), rather than the base type specifier. This is a critical parsing rule in C++ that affects multiple declarations on a single line.
// Syntax: T* identifier; OR T *identifier;

int* ptr1;        // ptr1 is of type 'pointer to int'
const char* ptr2; // ptr2 is of type 'pointer to const char'

// Binding demonstration:
int* ptr3, var1;  // ptr3 is 'pointer to int', var1 is 'int'
int *ptr4, *ptr5; // Both ptr4 and ptr5 are 'pointer to int'

2. Unary Indirection (Dereference) Operator

In an expression context, when used as a prefix unary operator, * performs indirection. It takes a pointer operand and yields an lvalue representing the object or function at the memory address held by the pointer. If the operand is of type T* (pointer to T), the resulting expression is of type T. This requires T to be an object type or a function type; consequently, pointers to void (void*) cannot be dereferenced. Because it yields an lvalue, the dereferenced pointer can be used on the left side of an assignment to mutate the underlying memory.
// Syntax: *expression

int val = 10;
int* ptr = &val;

*ptr = 20;          // Yields an lvalue; mutates the memory at the address
int readVal = *ptr; // Yields an lvalue; reads the memory at the address
Overloading: The unary * operator can be overloaded for user-defined types by defining T& operator*().
struct SmartPointer {
    int* internal_ptr;
    int& operator*() const {
        return *internal_ptr;
    }
};

3. Binary Multiplication Operator

When placed between two operands in an expression context, * functions as the binary arithmetic multiplication operator. It computes the product of the left-hand side (lhs) and right-hand side (rhs) operands. The compiler applies standard conversions (such as floating-integral conversions or integral promotions) to the operands before performing the operation to bring them to a common type. The result is a prvalue (pure rvalue).
// Syntax: lhs * rhs

int a = 5;
double b = 4.2;
double product = a * b; // 'a' undergoes a standard floating-integral conversion to double before multiplication
Overloading: The binary * operator can be overloaded for user-defined types by defining a non-member function T operator*(const T& lhs, const T& rhs) or a member function T operator*(const T& rhs) const.
struct Vector2D {
    float x, y;
    // Overloading binary * for scalar multiplication
    Vector2D operator*(float scalar) const {
        return {x * scalar, y * scalar};
    }
};

4. Pointer-to-Member Declaration

A specialized syntactic use of * occurs in conjunction with the scope resolution operator :: to declare a pointer to a non-static class member. This creates a type that holds the offset of a member within a class layout, rather than an absolute memory address.
// Syntax: T ClassName::* identifier;

struct Data {
    int value;
};

// Declares a pointer to an integer member of the Data struct
int Data::* memberPtr = &Data::value; 
Master C++ with Deep Grasping Methodology!Learn More