General topics | ||||||||||||||||
Flow control | ||||||||||||||||
Conditional execution statements | ||||||||||||||||
Iteration statements (loops) | ||||||||||||||||
Jump statements | ||||||||||||||||
Functions | ||||||||||||||||
Function declaration | ||||||||||||||||
Lambda function expression | ||||||||||||||||
inline specifier | ||||||||||||||||
Dynamic exception specifications(until C++17*) | ||||||||||||||||
noexcept specifier(C++11) | ||||||||||||||||
Exceptions | ||||||||||||||||
Namespaces | ||||||||||||||||
Types | ||||||||||||||||
Specifiers | ||||||||||||||||
| ||||||||||||||||
Storage duration specifiers | ||||||||||||||||
Initialization | ||||||||||||||||
Expressions | ||||||||||||||||
Alternative representations | ||||||||||||||||
Literals | ||||||||||||||||
Boolean -Integer -Floating-point | ||||||||||||||||
Character -String -nullptr(C++11) | ||||||||||||||||
User-defined(C++11) | ||||||||||||||||
Utilities | ||||||||||||||||
Attributes(C++11) | ||||||||||||||||
Types | ||||||||||||||||
typedef declaration | ||||||||||||||||
Type alias declaration(C++11) | ||||||||||||||||
Casts | ||||||||||||||||
Memory allocation | ||||||||||||||||
Classes | ||||||||||||||||
Class-specific function properties | ||||||||||||||||
| ||||||||||||||||
Special member functions | ||||||||||||||||
Templates | ||||||||||||||||
Miscellaneous | ||||||||||||||||
Non-static data members are declared in amember specification of a class.
class S{int n;// non-static data memberint& r;// non-static data member of reference typeint 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};
Anysimple declarations are allowed, except
| (since C++11) |
C
cannot have a non-static data member of typeC
, although it can have a non-static data member of typeC&
(reference to C) orC*
(pointer toC
);
| (since C++11) |
In addition,bit-field declarations are allowed.
Contents |
When an object of some classC
is created, each non-static data member of non-reference type is allocated in some part of the object representation ofC
. Whether reference members occupy any storage is implementation-defined, but theirstorage 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) membersnot separated by anaccess specifier(until C++11)with the samemember access(since C++11) are always allocated so that the members declared later have higher addresses within a class object. Membersseparated 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 bestandard-layout and to have properties described below if and only if it is aPOD 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 asstandard-layout class (seestandard-layout class for the list of requirements). | (since C++11) |
Thecommon 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{constint b1;volatilechar 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{unsignedint e;char b;};// A and E's common initial sequence is empty
Two standard-layout non-union class types are calledlayout-compatible if they are the same type ignoring cv-qualifiers, if any, are layout-compatibleenumerations (i.e. enumerations with the same underlying type), or if theircommon initial sequence consists of every non-static data member and bit-field (in the example above,A
andB
are layout-compatible).
Two standard-layout unions are calledlayout-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 memberm
of another union member of non-union class typeT2
providedm
is part of the common initial sequence ofT1
andT2
(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 thatstrict aliasing rules still apply to the result of such cast.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 adefault member initializer, which is a brace or equalsinitializer 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. Run this code #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 ranstd::cout<< x<<'\n';// prints 1 S s2(7);// default initializer did not runstd::cout<< x<<'\n';// prints 1}
Members of array type cannot deduce their size from member initializers: struct X{int a[]={1,2,3};// errorint b[3]={1,2,3};// OK}; Default member initializers are not allowed to cause the implicit definition of a defaulteddefault 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 formember initializer lists): struct A{ A()=default;// OK A(int v): v(v){}// OKconstint& v=42;// OK}; A a1;// error: ill-formed binding of temporary to referenceA a2(1);// OK (default member initializer ignored because v appears in a constructor)// however a2.v is a dangling reference | (since C++11) |
Ifa reference member is initialized from its default member initializer(until C++20)a member has a default member initializer(since C++20) and apotentially-evaluated subexpression thereof is anaggregate 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}};// OKconst 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
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 membervoid(S::*fp)()=&S::f;// OK: use of f to make a pointer to member
struct S{int m;staticconststd::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 | Feature |
---|---|---|---|
__cpp_nsdmi | 200809L | (C++11) | Non-static data member initializers |
__cpp_aggregate_nsdmi | 201304L | (C++14) | Aggregate classes withdefault 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 |
CWG 2759 | C++20 | common initial sequence could include members declared [[no_unique_address]] | they are not included |
classes | |
static members | |
non-static member functions | |
(C++11) | checks if a type is astandard-layout type (class template)[edit] |
byte offset from the beginning of astandard-layout type to specified member (function macro)[edit] |