Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Object

      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
       
       

      C++ programs create, destroy, refer to, access, and manipulateobjects.

      An object, in C++, has

      The following entities are not objects: value, reference, function, enumerator, type, non-static class member, template, class or function template specialization, namespace, parameter pack, andthis.

      Avariable is an object or a reference that is not a non-static data member, that is introduced by adeclaration.

      Contents

      [edit]Object creation

      Objects can be explicitly created bydefinitions,new expressions,throw expressions, changing the active member of aunion and evaluating expressions that requiretemporary objects. The created object is uniquely defined in explicit object creation.

      Objects ofimplicit-lifetime types can also be implicitly created by

      • except during constant evaluation, operations that begin lifetime of an array of typeunsignedchar orstd::byte(since C++17), in which case such objects are created in the array,
      • call to following allocating functions, in which case such objects are created in the allocated storage:
      (since C++17)
      • call to followingobject representation copying functions, in which case such objects are created in the destination region of storage or the result:
      (since C++20)
      • call to following specific functions, in which case such objects are created in the specified region of storage:
      • std::start_lifetime_as
      • std::start_lifetime_as_array
      (since C++23)

      Zero or more objects may be created in the same region of storage, as long as doing so would give the program defined behavior. If such creation is impossible, e.g. due to conflicting operations, the behavior of the program is undefined. If multiple such sets of implicitly created objects would give the program defined behavior, it is unspecified which such set of objects is created. In other words, implicitly created objects are not required to be uniquely defined.

      After implicitly creating objects within a specified region of storage, some operations produce a pointer to asuitable created object. The suitable created object has the same address as the region of storage. Likewise, the behavior is undefined if only if no such pointer value can give the program defined behavior, and it is unspecified which pointer value is produced if there are multiple values giving the program defined behavior.

      #include <cstdlib> struct X{int a, b;}; X* MakeX(){// One of possible defined behaviors:// the call to std::malloc implicitly creates an object of type X// and its subobjects a and b, and returns a pointer to that X object    X* p=static_cast<X*>(std::malloc(sizeof(X)));    p->a=1;    p->b=2;return p;}

      Call tostd::allocator::allocate or implicitly defined copy/move special member functions ofunion types can also create objects.

      [edit]Object representation and value representation

      Some types and objects haveobject representations andvalue representations, they are defined in the table below:

      EntityObject representationValue representation
      a complete object typeTthe sequence ofNunsignedchar objects taken up by a non-bit-field complete object of typeT, whereN issizeof(T)the set of bits in the object representation ofT that participate in representing a value of typeT
      a non-bit-field complete objectobj of typeTthe bytes ofobj corresponding to the object representation ofTthe bits ofobj corresponding to the value representation ofT
      a bit-field objectbfthe sequence ofN bits taken up bybf, whereN is the width of the bit-fieldthe set of bits in the object representation ofbf that participate in representing the value ofbf

      Bits in the object representation of a type or object that are not part of the value representation arepadding bits.

      ForTriviallyCopyable types, value representation is a part of the object representation, which means that copying the bytes occupied by the object in the storage is sufficient to produce another object with the same value (except if the object is a potentially-overlapping subobject, or the value is atrap representation of its type and loading it into the CPU raises a hardware exception, such as SNaN ("signalling not-a-number") floating-point values or NaT ("not-a-thing") integers).

      Although most implementations do not allow trap representations, padding bits, or multiple representations for integer types, there are exceptions; for example a value of an integer type on Itaniummay be a trap representation.

      The reverse is not necessarily true: two objects of aTriviallyCopyable type with different object representations may represent the same value. For example, multiple floating-point bit patterns represent the same special valueNaN. More commonly, padding bits may be introduced to satisfyalignment requirements,bit-field sizes, etc.

      #include <cassert> struct S{char c;// 1 byte value// 3 bytes of padding bits (assuming alignof(float) == 4)float f;// 4 bytes value (assuming sizeof(float) == 4) bool operator==(const S& arg)const// value-based equality{return c== arg.c&& f== arg.f;}}; void f(){assert(sizeof(S)==8);    S s1={'a',3.14};    S s2= s1;reinterpret_cast<unsignedchar*>(&s1)[2]='b';// modify some padding bitsassert(s1== s2);// value did not change}

      For the objects of typechar,signedchar, andunsignedchar (unless they are oversizebit-fields), every bit of the object representation is required to participate in the value representation and each possible bit pattern represents a distinct value (no padding bits, trap bits, or multiple representations allowed).

      [edit]Subobjects

      An object can havesubobjects. These include

      • member objects
      • base class subobjects
      • array elements

      An object that is not a subobject of another object is calledcomplete object.

      If a complete object, a member subobject, or an array element is ofclass type, its type is considered themost derived class , to distinguish it from the class type of any base class subobject. An object of a most derived class type or of a non-class type is called amost derived object .

      For a class,

      are called itspotentially constructed subobjects.

      [edit]Size

      A subobject is apotentially overlapping subobject if it is a base class subobject or a non-static data member declared with the[[no_unique_address]] attribute(since C++20).

      An objectobj can only possibly have zero size if all following conditions are satisfied:

      • obj is a potentially-overlapping subobject.
      • obj is of a class type without virtual member functions and virtual base classes.
      • obj does not have any subobject of nonzero size or unnamedbit-fields of nonzero length.

      For an objectobj satisfying all the conditions above:

      • Ifobj is a base class subobject of astandard-layout(since C++11) class type with no non-static data members, it has zero size.
      • Otherwise, it is implementation-defined under which circumstances whereobj has zero size.

      Seeempty base optimization for more details.

      Any non-bit-field object with nonzero size must occupy one or more bytes of storage, including every byte that is occupied (in full or in part) by any of its subobjects. The storage occupied must be contiguous if the object is of trivially copyable or standard-layout(since C++11) type.

      [edit]Address

      Unless an object is a bit-field or a subobject of zero size, theaddress of that object is the address of the firstbyte it occupies.

      An object can contain other objects, in which case the contained objects arenested within the former object. An objecta is nested within another objectb if any of the following conditions is satisfied:

      • a is a subobject ofb.
      • bprovides storage fora.
      • There exists an objectc wherea is nested withinc, andc is nested withinb.

      An object is apotentially non-unique object if it is one of the following objects:

      (since C++11)
      • A subobject of a potentially non-unique object.

      For any two non-bit-field objects with overlappinglifetimes:

      • If any of the following conditions is satisfied, they may have the same address:
      • One of them is nested within the other.
      • Any of them is a subobject of zero size, and their types are notsimilar.
      • They are both potentially non-unique objects.
      • Otherwise, they always have distinct addresses and occupy disjoint bytes of storage.
      // character literals are always uniquestaticconstchar test1='x';staticconstchar test2='x';constbool b=&test1!=&test2;// always true // the character 'x' accessed from “r”, “s” and “il”// may have the same address (i.e., these objects may share storage)staticconstchar(&r)[]="x";staticconstchar*s="x";staticstd::initializer_list<char> il={'x'};constbool b2= r!= il.begin();// unspecified resultconstbool b3= r!= s;// unspecified resultconstbool b4= il.begin()!=&test1;// always trueconstbool b5= r!=&test1;// always true

      [edit]Polymorphic objects

      Objects of a class type that declares or inherits at least one virtual function are polymorphic objects. Within each polymorphic object, the implementation stores additional information (in every existing implementation, it is one pointer unless optimized out), which is used byvirtual function calls and by the RTTI features (dynamic_cast andtypeid) to determine, at run time, the type with which the object was created, regardless of the expression it is used in.

      For non-polymorphic objects, the interpretation of the value is determined from the expression in which the object is used, and is decided at compile time.

      Run this code
      #include <iostream>#include <typeinfo> struct Base1{// polymorphic type: declares a virtual membervirtual ~Base1(){}}; struct Derived1: Base1{// polymorphic type: inherits a virtual member}; struct Base2{// non-polymorphic type}; struct Derived2: Base2{// non-polymorphic type}; int main(){    Derived1 obj1;// object1 created with type Derived1    Derived2 obj2;// object2 created with type Derived2     Base1& b1= obj1;// b1 refers to the object obj1    Base2& b2= obj2;// b2 refers to the object obj2 std::cout<<"Expression type of b1: "<<typeid(decltype(b1)).name()<<'\n'<<"Expression type of b2: "<<typeid(decltype(b2)).name()<<'\n'<<"Object type of b1: "<<typeid(b1).name()<<'\n'<<"Object type of b2: "<<typeid(b2).name()<<'\n'<<"Size of b1: "<< sizeof b1<<'\n'<<"Size of b2: "<< sizeof b2<<'\n';}

      Possible output:

      Expression type of b1: Base1Expression type of b2: Base2Object type of b1: Derived1Object type of b2: Base2Size of b1: 8Size of b2: 1

      [edit]Strict aliasing

      Accessing an object using an expression of a type other than the type with which it was created is undefined behavior in many cases, seereinterpret_cast for the list of exceptions and examples.

      [edit]Alignment

      Everyobject type has the property calledalignment requirement, which is a nonnegative integer value (of typestd::size_t, and always a power of two) representing the number of bytes between successive addresses at which objects of this type can be allocated.

      The alignment requirement of a type can be queried withalignof orstd::alignment_of. The pointer alignment functionstd::align can be used to obtain a suitably-aligned pointer within some buffer.std::aligned_storage can be used to obtain suitably-aligned storage.(until C++23)

      (since C++11)

      Each object type imposes its alignment requirement on every object of that type; stricter alignment (with larger alignment requirement) can be requested usingalignas(since C++11). Attempting to create an object in storage that does not meet the alignment requirements of the object's type is undefined behavior.

      In order to satisfy alignment requirements of all non-static members of aclass,padding bits may be inserted after some of its members.

      Run this code
      #include <iostream> // objects of type S can be allocated at any address// because both S.a and S.b can be allocated at any addressstruct S{char a;// size: 1, alignment: 1char b;// size: 1, alignment: 1};// size: 2, alignment: 1 // objects of type X must be allocated at 4-byte boundaries// because X.n must be allocated at 4-byte boundaries// because int's alignment requirement is (usually) 4struct X{int n;// size: 4, alignment: 4char c;// size: 1, alignment: 1// three bytes of padding bits};// size: 8, alignment: 4 int main(){std::cout<<"alignof(S) = "<< alignof(S)<<'\n'<<"sizeof(S)  = "<< sizeof(S)<<'\n'<<"alignof(X) = "<< alignof(X)<<'\n'<<"sizeof(X)  = "<< sizeof(X)<<'\n';}

      Possible output:

      alignof(S) = 1sizeof(S)  = 2alignof(X) = 4sizeof(X)  = 8

      The weakest alignment (the smallest alignment requirement) is the alignment ofchar,signedchar, andunsignedchar, which equals1; the largestfundamental alignment of any type is implementation-defined and equal to the alignment ofstd::max_align_t(since C++11).

      Fundamental alignments are supported for objects of all kinds of storage durations.

      If a type's alignment is made stricter (larger) thanstd::max_align_t usingalignas, it is known as a type withextended alignment requirement. A type whose alignment is extended or a class type whose non-static data member has extended alignment is anover-aligned type.

      Allocator types are required to handle over-aligned types correctly.

      (since C++11)


      It is implementation-defined ifnew expressions and(until C++17)std::get_temporary_buffer support over-aligned types.

      (since C++11)
      (until C++20)

      [edit]Notes

      Objects in C++ have different meaning from objects inobject-oriented programming (OOP):

      Objects in C++Objects in OOP
      can have any object type
      (seestd::is_object)
      must have a class type
      no concept of “instance”have the concept of “instance” (and there are mechanisms likeinstanceof to detect “instance-of” relationship)
      no concept of “interface”have the concept of “interface” (and there are mechanisms likeinstanceof to detect whether an interface is implemented)
      polymorphism needs to be explicitly enabled via virtual memberspolymorphism is always enabled

      In the defect reportP0593R6, implicit object creation was considered happening when creating a byte array or invocating anallocation function (which is possibly user-defined andconstexpr) during constant evaluation. However, such allowance caused indeterminism in constant evaluation which was undesired and uninplementable in some aspects. As a result,P2747R2 disallowed such implicit object creation in constant evaluation. We intentedly treat such change as a defect report although the whole paper is not.

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 633C++98variables could only be objectsthey can also be references
      CWG 734C++98it was unspecified whether variables defined
      in the same scope that are guaranteed to have
      the same value can have the same address
      address is guaranteed to be
      different if their lifetimes overlap,
      regardless of their values
      CWG 1189C++98two base class subobjects of the same
      type could have the same address
      they always have
      distinct addresses
      CWG 1861C++98for oversize bit-fields of narrow character
      types, all bits of the object representation
      still participated in the value representation
      allows padding bits
      CWG 2489C++98char[] cannot provide storage, but objects
      could be implicitly created within its storage
      objects cannot be implicitly created
      within the storage ofchar[]
      CWG 2519C++98the definition of object representation did not address bit-fieldsaddresses bit-fields
      CWG 2719C++98the behavior of creating an object
      in misaligned storage was unclear
      the behavior is
      undefined in this case
      CWG 2753C++11it was unclear whether a backing array of an
      initializer list can share storage with a string literal
      they can share storage
      CWG 2795C++98when determining whether two objects with overlapping
      lifetimes can have the same address, if any of them is a
      subobject of zero size, they could have similar distinct types
      only allows non-similar types
      P0593R6C++98previous object model did not support many
      useful idioms required by the standard library
      and was not compatible with effective types in C
      implicit object creation added

      [edit]See also

      C documentation forObject
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/object&oldid=180943"

      [8]ページ先頭

      ©2009-2025 Movatter.jp