Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Non-static data members

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      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
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      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

      • thread_local storage class specifier is not allowed (but it is allowed forstatic data members);
      (since C++11)
      • incomplete types,abstract class types, and arrays thereof are not allowed: in particular, a classC 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);
      • a non-static data member cannot have the same name as the name of the class if at least one user-declared constructor is present;
      (since C++11)

      In addition,bit-field declarations are allowed.

      Contents

      [edit]Layout

      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.

      [edit]Standard-layout

      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

      • if__has_cpp_attribute(no_unique_address) is not0, neither entity is declared with[[no_unique_address]] attribute,
      (since C++20)
      • corresponding entities have layout-compatible types,
      • corresponding entities have the samealignment requirements, and
      • either both entities are bit-fields with the same width or neither is a bit-field.
      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:

      • In a standard-layout union with an active member of non-union class typeT1, 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).
      • A pointer to an object of standard-layout class type can bereinterpret_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.
      • The macrooffsetof may be used to determine the offset of any member from the beginning of a standard-layout class.

      [edit]Member initialization

      Non-static data members may be initialized in one of two ways:

      1) In themember initializer list of the constructor.
      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}

      Default member initializers are not allowed forbit-field members.

      (until C++20)

      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)

      [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 implicitthis-> member access expressions that appear when a non-static member name is used in any of the contexts wherethis 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 apointer to non-static member.
      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
      3) (for data members only, not member functions) When used inunevaluated operands.
      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
      Notes: such uses are allowed via the resolution ofCWG issue 613 inN2253, which is treated as a change in C++11 by some compilers (e.g. clang).

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_nsdmi200809L(C++11)Non-static data member initializers
      __cpp_aggregate_nsdmi201304L(C++14)Aggregate classes withdefault member initializers

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 80C++98all 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 190C++98when determining layout compatibility,
      all members were considered
      only consider non-
      static data members
      CWG 613C++98unevaluated uses of non-static data members not allowedsuch uses are allowed
      CWG 645C++98it was unspecified whether bit-field and
      non-bit-field members are layout compatible
      not layout compatible
      CWG 1397C++11class was regarded as complete
      in the default member initializers
      default member init cannot trigger
      definition of default constructor
      CWG 1425C++98it 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 1696C++98reference members could be initialized to temporaries
      (whose lifetime would end at the end of constructor)
      such init is ill-formed
      CWG 1719C++98differently cv-qualified types weren't layout-compatiblecv-quals ignored, spec improved
      CWG 2254C++11pointer 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 2583C++11common initial sequence did not
      consider alignment requirements
      considered
      CWG 2759C++20common initial sequence could include
      members declared[[no_unique_address]]
      they are not included

      [edit]See also

      classes
      static members
      non-static member functions
      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]
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/data_members&oldid=168790"

      [8]ページ先頭

      ©2009-2025 Movatter.jp