Non-static data members are declared in a member specification of a class.
class S
{
    int n;              // non-static data member
    int& r;             // non-static data member of reference type
    int a[2] = {1, 2};  // non-static data member with default member initializer (C++11)
    std::string s, *ps; // two non-static data members
 
    struct NestedS
    {
        std::string s;
    } d5;               // non-static data member of nested type
 
    char bit : 2;       // two-bit bitfield
};Any simple declarations are allowed, except.
| 
 | (since C++11) | 
C cannot have a non-static data member of type C, although it can have a non-static data member of type C& (reference to C) or C* (pointer to C); | 
 | (since C++11) | 
In addition, bit-field declarations are allowed.
When an object of some class C is created, each non-static data member of non-reference type is allocated in some part of the object representation of C. Whether reference members occupy any storage is implementation-defined, but their storage duration is the same as that of the object in which they are members.
| For non-union class types, non-zero-sized (since C++20) members not separated by an access specifier (until C++11)with the same member access (since C++11) are always allocated so that the members declared later have higher addresses within a class object. Members separated by an access specifier (until C++11)with different access control (since C++11) are allocated in unspecified order (the compiler may group them together). | (until C++23) | 
| For non-union class types, non-zero-sized members are always allocated so that the members declared later have higher addresses within a class object. Note that access control of member still affects the standard-layout property (see below). | (since C++23) | 
Alignment requirements may necessitate padding between members, or after the last member of a class.
| A class is considered to be standard-layout and to have properties described below if and only if it is a POD class. | (until C++11) | 
| A class where all non-static data members have the same access control and certain other conditions are satisfied is known as standard-layout class (see standard-layout class for the list of requirements). | (since C++11) | 
The common initial sequence of two standard-layout non-union class types is the longest sequence of non-static data members and bit-fields in declaration order, starting with the first such entity in each of the classes, such that.
| 
 | (since C++20) | 
struct A { int a; char b; };
struct B { const int b1; volatile char b2; }; 
// A and B's common initial sequence is A.a, A.b and B.b1, B.b2
 
struct C { int c; unsigned : 0; char b; };
// A and C's common initial sequence is A.a and C.c
 
struct D { int d; char b : 4; };
// A and D's common initial sequence is A.a and D.d
 
struct E { unsigned int e; char b; };
// A and E's common initial sequence is emptyTwo standard-layout non-union class types are called layout-compatible if they are the same type ignoring cv-qualifiers, if any, are layout-compatible enumerations (i.e. enumerations with the same underlying type), or if their common initial sequence consists of every non-static data member and bit-field (in the example above, A and B are layout-compatible).
Two standard-layout unions are called layout-compatible if they have the same number of non-static data members and corresponding non-static data members (in any order) have layout-compatible types.
Standard-layout types have the following special properties:
T1, it is permitted to read a non-static data member m of another union member of non-union class type T2 provided m is part of the common initial sequence of T1 and T2 (except that reading a volatile member through non-volatile glvalue is undefined). offsetof may be used to determine the offset of any member from the beginning of a standard-layout class. Non-static data members may be initialized in one of two ways:
struct S
{
    int n;
    std::string s;
    S() : n(7) {} // direct-initializes n, default-initializes s
};| 2) Through a default member initializer, which is a brace or equals initializer included in the member declaration and is used if the member is omitted from the member initializer list of a constructor. struct S
{
    int n = 7;
    std::string s{'a', 'b', 'c'};
    S() {} // default member initializer will copy-initialize n, list-initialize s
};If a member has a default member initializer and also appears in the member initialization list in a constructor, the default member initializer is ignored for that constructor. #include <iostream>
 
int x = 0;
struct S
{
    int n = ++x;
    S() {}                 // uses default member initializer
    S(int arg) : n(arg) {} // uses member initializer 
};
 
int main()
{
    std::cout << x << '\n'; // prints 0
    S s1;                   // default initializer ran
    std::cout << x << '\n'; // prints 1
    S s2(7);                // default initializer did not run
    std::cout << x << '\n'; // prints 1
}
 Members of array type cannot deduce their size from member initializers: struct X
{
    int a[] = {1, 2, 3};  // error
    int b[3] = {1, 2, 3}; // OK
};Default member initializers are not allowed to cause the implicit definition of a defaulted default constructor for the enclosing class or the exception specification of that constructor: struct node
{
    node* p = new node; // error: use of implicit or defaulted node::node() 
};Reference members cannot be bound to temporaries in a default member initializer (note; same rule exists for member initializer lists): struct A
{
    A() = default;     // OK
    A(int v) : v(v) {} // OK
    const int& v = 42; // OK
};
 
A a1;    // error: ill-formed binding of temporary to reference
A a2(1); // OK (default member initializer ignored because v appears in a constructor)
         // however a2.v is a dangling reference | (since C++11) | 
| If a reference member is initialized from its default member initializer (until C++20)a member has a default member initializer (since C++20) and a potentially-evaluated subexpression thereof is an aggregate initialization that would use that default member initializer, the program is ill-formed: struct A;
extern A a;
 
struct A
{
    const A& a1{A{a, a}}; // OK
    const A& a2{A{}};     // error
};
 
A a{a, a};                // OK | (since C++17) | 
The name of a non-static data member or a non-static member function can only appear in the following three situations:
this-> member access expressions that appear when a non-static member name is used in any of the contexts where this is allowed (inside member function bodies, in member initializer lists, in the in-class default member initializers). struct S
{
    int m;
    int n;
    int x = m;            // OK: implicit this-> allowed in default initializers (C++11)
 
    S(int i) : m(i), n(m) // OK: implicit this-> allowed in member initializer lists
    {
        this->f();        // explicit member access expression
        f();              // implicit this-> allowed in member function bodies
    }
 
    void f();
};struct S
{
    int m;
    void f();
};
 
int S::*p = &S::m;       // OK: use of m to make a pointer to member
void (S::*fp)() = &S::f; // OK: use of f to make a pointer to memberstruct S
{
    int m;
    static const std::size_t sz = sizeof m; // OK: m in unevaluated operand
};
 
std::size_t j = sizeof(S::m + 42); // OK: even though there is no "this" object for m| Feature-test macro | Value | Std | Comment | 
|---|---|---|---|
| __cpp_nsdmi | 200809L | (C++11) | Non-static data member initializers | 
| __cpp_aggregate_nsdmi | 201304L | (C++14) | Aggregate classes with default member initializers | 
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
| DR | Applied to | Behavior as published | Correct behavior | 
|---|---|---|---|
| CWG 80 | C++98 | all data members cannot have the same name as the name of the class (breaks C compatibility) | allow non-static data members share the class name if there is no user-declared constructor | 
| CWG 190 | C++98 | when determining layout compatibility, all members were considered | only consider non- static data members | 
| CWG 613 | C++98 | unevaluated uses of non-static data members not allowed | such uses are allowed | 
| CWG 645 | C++98 | it was unspecified whether bit-field and non-bit-field members are layout compatible | not layout compatible | 
| CWG 1397 | C++11 | class was regarded as complete in the default member initializers | default member init cannot trigger definition of default constructor | 
| CWG 1425 | C++98 | it was unclear whether a standard-layout object shares the same address with the first non-static data member or the first base class subobject | non-static data member if present, otherwise base class subobject if present | 
| CWG 1696 | C++98 | reference members could be initialized to temporaries (whose lifetime would end at the end of constructor) | such init is ill-formed | 
| CWG 1719 | C++98 | differently cv-qualified types weren't layout-compatible | cv-quals ignored, spec improved | 
| CWG 2254 | C++11 | pointer to standard-layout class with no data members can be reinterpret_cast to its first base class | can be reinterpret_cast to any of its base classes | 
| CWG 2583 | C++11 | common initial sequence did not consider alignment requirements | considered | 
| classes | |
| static members | |
| non-static member functions | |
| (C++11) | checks if a type is a standard-layout type (class template) | 
| byte offset from the beginning of a standard-layout type to specified member (function macro) | |
    © cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
    https://en.cppreference.com/w/cpp/language/data_members