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
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
);In addition, bit-field declarations are allowed.
[edit] LayoutWhen 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.
[edit] Standard-layoutA 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
[[no_unique_address]]
attribute,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 empty
Two 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).reinterpret_cast
to pointer to its first non-static non-bitfield data member (if it has non-static data members) or otherwise any of its base class subobjects (if it has any), and vice versa. In other words, padding is not allowed before the first data member of a standard-layout type. Note that strict aliasing rules still apply to the result of such cast.Non-static data members may be initialized in one of two ways:
2)Through a
default member initializer, which is a brace or equals
initializerincluded 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 }
Default member initializers are not allowed for bit-field members.
(until C++20)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) [edit] Usage
The name of a non-static data member or a non-static member function can only appear in the following three situations:
1)As a part of class member access expression, in which the class either has this member or is derived from a class that has this member, including the implicit
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(); };2)
To form a
pointer to non-static member.
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 member3)
(for data members only, not member functions) When used in
unevaluated operands.
struct 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
Notes: such uses are allowed via the resolution of
CWG issue 613in
N2253, which is treated as a change in C++11 by some compilers (e.g. clang).
[edit] Notes [edit] Defect reportsThe 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[[no_unique_address]]
they are not included [edit] See also
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4