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.

A struct (structure) in C++ is a user-defined composite data type that aggregates multiple variables of potentially different types into a single, contiguous memory block. In C++, a struct is fundamentally identical to a class in terms of capabilities, with the sole semantic distinction being that its members and base classes default to public access rather than private.

Syntax and Declaration

A struct is declared using the struct keyword, optionally followed by an identifier, and a block containing its member declarations. The identifier can be omitted (creating an unnamed struct) if an instance is declared immediately before the terminating semicolon. Naming the struct is the standard practice for reusable types.
// Named struct
struct Identifier {
    // Data members
    int integerMember;
    double doubleMember;

    // Member functions
    void memberFunction() {
        // Implementation
    }
}; 

// Unnamed struct with immediate instantiation
struct {
    int x;
    int y;
} unnamedObj;

Access Modifiers and Inheritance

By default, all members of a struct are public. You can explicitly use private or protected access specifiers to encapsulate data, exactly as you would in a class.
struct AccessExample {
    int a; // Public by default

private:
    int b; // Explicitly private
};
When a struct inherits from another struct or class, the default inheritance mode is public.
class BaseClass {};

struct DerivedStruct : BaseClass {
    // Inherits BaseClass publicly by default
};

Instantiation and Member Access

Instances of a struct are created like any standard type. Members are accessed using the dot (.) operator for direct object references, or the arrow (->) operator for pointers to the struct.
Identifier obj;
obj.integerMember = 42;       // Direct access

Identifier* ptr = &obj;
ptr->doubleMember = 3.14;     // Pointer access

Initialization and Aggregate Rules

C++ provides multiple ways to initialize a struct. If the struct qualifies as an aggregate, it can be initialized using aggregate initialization. The strict definition of an aggregate depends on the C++ standard in use:
  • C++11: An aggregate is an array or a class/struct with no user-provided constructors, no private or protected non-static data members, no base classes, no virtual functions, and no default member initializers (brace-or-equal initializers).
  • C++14: The rules are identical to C++11, except default member initializers are permitted.
  • C++17: Public, non-virtual base classes are permitted. However, the struct must not have any explicit constructors (even if explicitly defaulted or deleted).
  • C++20 and later: The rules are stricter. A struct is only an aggregate if it has no user-declared constructors whatsoever. Any explicitly declared constructor, even if defaulted or deleted, disables aggregate initialization.
struct Point {
    int x;
    int y;
};

// Aggregate initialization (C-style)
Point p1 = {10, 20};

// Uniform initialization (C++11 and later)
Point p2{30, 40};

// Designated initializers (C++20 and later)
Point p3{.x = 50, .y = 60};
If a struct does not meet the aggregate criteria for the compiled standard, aggregate initialization is invalid, and the struct must be initialized via a constructor.
struct ConstructedPoint {
    int x;
    int y;

    // User-provided constructor disables aggregate initialization in all C++ versions
    ConstructedPoint(int xVal, int yVal) : x(xVal), y(yVal) {}
};

ConstructedPoint p4(10, 20);

Memory Layout, Padding, and Alignment

For members sharing the same access control (e.g., all public), the memory layout of a struct guarantees they are allocated sequentially in the order they are declared. Prior to C++23, the relative memory order of members with differing access controls (such as a public member followed by a private member) is explicitly left unspecified by the standard. As of C++23, sequential allocation is guaranteed regardless of access specifiers. However, the total size of the struct in memory is rarely the exact sum of its members’ sizes. To satisfy hardware alignment requirements, the compiler automatically inserts padding bytes between members. The struct itself will also be padded at the end so that its total size is a multiple of its strictest member’s alignment requirement.
struct PaddedStruct {
    char a;     // 1 byte
                // 3 bytes padding (assuming 4-byte alignment boundary)
    int b;      // 4 bytes
    char c;     // 1 byte
                // 3 bytes padding
};              // Total size: 12 bytes (not 6 bytes)

C++ Specific Capabilities

Unlike C-style structs, a C++ struct fully supports Object-Oriented Programming paradigms. A C++ struct can contain:
  • Constructors and Destructors
  • Member functions (methods)
  • Static members
  • Operator overloading
  • Virtual functions (polymorphism)
  • Access specifiers (public, private, protected)
Master C++ with Deep Grasping Methodology!Learn More