Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Pointer declaration

      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
       
      Declarations
       

      Declares a variable of a pointer or pointer-to-member type.

      Contents

      [edit]Syntax

      A pointer declaration is any simple declaration whosedeclarator has the form

      *attr (optional)cv (optional)declarator (1)
      nested-name-specifier*attr (optional)cv (optional)declarator (2)
      1)Pointer declarator: the declarationS* D; declaresD as a pointer to the type determined by thedeclaration specifier sequenceS.
      2)Pointer to member declarator: the declarationS C::* D; declaresD as a pointer to non-static member ofC of type determined by the declaration specifier sequenceS.
      nested-name-specifier - asequence of names and scope resolution operators::
      attr -(since C++11) a list ofattributes
      cv - const/volatile qualification which apply to the pointer that is being declared (not to the pointed-to type, whose qualifications are part of declaration specifier sequence)
      declarator - anydeclarator

      There are no pointers toreferences and there are no pointers tobit-fields. Typically, mentions of "pointers" without elaboration do not include pointers to (non-static) members.

      [edit]Pointers

      Every value of pointer type is one of the following:

      • apointer to an object or function (in which case the pointer is said topoint to the object or function), or
      • apointer past the end of an object, or
      • thenull pointer value for that type, or
      • aninvalid pointer value.

      A pointer that points to an objectrepresents the address of the first byte in memory occupied by the object. A pointer past the end of an objectrepresents the address of the first byte in memory after the end of the storage occupied by the object.

      Note that two pointers that represent the same address may nonetheless have different values.

      struct C{int x, y;} c; int* px=&c.x;// value of px is "pointer to c.x"int* pxe= px+1;// value of pxe is "pointer past the end of c.x"int* py=&c.y;// value of py is "pointer to c.y" assert(pxe== py);// == tests if two pointers represent the same address// may or may not fire *pxe=1;// undefined behavior even if the assertion does not fire

      Indirection through an invalid pointer value and passing an invalid pointer value to a deallocation function have undefined behavior. Any other use of an invalid pointer value has implementation-defined behavior. Some implementations might define that copying an invalid pointer value causes a system-generated runtime fault.

      [edit]Pointers to objects

      A pointer to object can be initialized with the return value of theaddress-of operator applied to any expression of object type, including another pointer type:

      int n;int* np=&n;// pointer to intint*const* npp=&np;// non-const pointer to const pointer to non-const int int a[2];int(*ap)[2]=&a;// pointer to array of int struct S{int n;}; S s={1};int* sp=&s.n;// pointer to the int that is a member of s

      Pointers may appear as operands to the built-in indirection operator (unaryoperator*), which returns thelvalue expression identifying the pointed-to object:

      int n;int* p=&n;// pointer to nint& r=*p;// reference is bound to the lvalue expression that identifies nr=7;// stores the int 7 in nstd::cout<<*p;// lvalue-to-rvalue implicit conversion reads the value from n

      Pointers to class objects may also appear as the left-hand operands of the member access operatorsoperator-> andoperator->*.

      Because of thearray-to-pointer implicit conversion, pointer to the first element of an array can be initialized with an expression of array type:

      int a[2];int* p1= a;// pointer to the first element a[0] (an int) of the array a int b[6][3][8];int(*p2)[3][8]= b;// pointer to the first element b[0] of the array b,// which is an array of 3 arrays of 8 ints

      Because of thederived-to-base implicit conversion for pointers, pointer to a base class can be initialized with the address of a derived class:

      struct Base{};struct Derived: Base{}; Derived d;Base* p=&d;

      IfDerived ispolymorphic, such a pointer may be used to makevirtual function calls.

      Certainaddition, subtraction,increment, and decrement operators are defined for pointers to elements of arrays: such pointers satisfy theLegacyRandomAccessIterator requirements and allow the C++ libraryalgorithms to work with raw arrays.

      Comparison operators are defined for pointers to objects in some situations: two pointers that represent the same address compare equal, two null pointer values compare equal, pointers to elements of the same array compare the same as the array indices of those elements, and pointers to non-static data members with the samemember access compare in order of declaration of those members.

      Many implementations also providestrict total ordering of pointers of random origin, e.g. if they are implemented as addresses within continuous virtual address space. Those implementations that do not (e.g. where not all bits of the pointer are part of a memory address and have to be ignored for comparison, or an additional calculation is required or otherwise pointer and integer is not a 1 to 1 relationship), provide a specialization ofstd::less for pointers that has that guarantee. This makes it possible to use all pointers of random origin as keys in standard associative containers such asstd::set orstd::map.

      [edit]Pointers tovoid

      Pointer to object of any type can beimplicitly converted to pointer to (possiblycv-qualified)void; the pointer value is unchanged. The reverse conversion, which requiresstatic_cast orexplicit cast, yields the original pointer value:

      int n=1;int* p1=&n;void* pv= p1;int* p2=static_cast<int*>(pv);std::cout<<*p2<<'\n';// prints 1

      If the original pointer is pointing to a base class subobject within an object of some polymorphic type,dynamic_cast may be used to obtain avoid* that is pointing at the complete object of the most derived type.

      Pointers tovoid have the same size, representation and alignment as pointers tochar.

      Pointers tovoid are used to pass objects of unknown type, which is common in C interfaces:std::malloc returnsvoid*,std::qsort expects a user-provided callback that accepts twoconstvoid* arguments.pthread_create expects a user-provided callback that accepts and returnsvoid*. In all cases, it is the caller's responsibility to cast the pointer to the correct type before use.

      [edit]Pointers to functions

      A pointer to function can be initialized with an address of a non-member function or a static member function. Because of thefunction-to-pointer implicit conversion, the address-of operator is optional:

      void f(int);void(*p1)(int)=&f;void(*p2)(int)= f;// same as &f

      Unlike functions or references to functions, pointers to functions are objects and thus can be stored in arrays, copied, assigned, etc.

      void(a[10])(int);// Error: array of functionsvoid(&a[10])(int);// Error: array of referencesvoid(*a[10])(int);// OK: array of pointers to functions

      Note: declarations involving pointers to functions can often be simplified with type aliases:

      using F=void(int);// named type alias to simplify declarationsF a[10];// Error: array of functionsF& a[10];// Error: array of referencesF* a[10];// OK: array of pointers to functions

      A pointer to function can be used as the left-hand operand of thefunction call operator, this invokes the pointed-to function:

      int f(int n){std::cout<< n<<'\n';return n* n;} int main(){int(*p)(int)= f;int x= p(7);}

      Dereferencing a function pointer yields the lvalue identifying the pointed-to function:

      int f();int(*p)()= f;// pointer p is pointing to fint(&r)()=*p;// the lvalue that identifies f is bound to a referencer();// function f invoked through lvalue reference(*p)();// function f invoked through the function lvaluep();// function f invoked directly through the pointer

      A pointer to function may be initialized from an overload set which may include functions, function template specializations, and function templates, if only one overload matches the type of the pointer (seeaddress of an overloaded function for more detail):

      template<typename T>T f(T n){return n;} double f(double n){return n;} int main(){int(*p)(int)= f;// instantiates and selects f<int>}

      Equality comparison operators are defined for pointers to functions (they compare equal if pointing to the same function).

      [edit]Pointers to members

      [edit]Pointers to data members

      A pointer to non-static member objectm which is a member of classC can be initialized with the expression&C::m exactly. Expressions such as&(C::m) or&m insideC's member function do not form pointers to members.

      Such a pointer may be used as the right-hand operand of thepointer-to-member access operatorsoperator.* andoperator->*:

      struct C{int m;}; int main(){int C::* p=&C::m;// pointer to data member m of class C    C c={7};std::cout<< c.*p<<'\n';// prints 7    C* cp=&c;    cp->m=10;std::cout<< cp->*p<<'\n';// prints 10}

      Pointer to data member of an accessible unambiguous non-virtual base class can beimplicitly converted to pointer to the same data member of a derived class:

      struct Base{int m;};struct Derived: Base{}; int main(){int Base::* bp=&Base::m;int Derived::* dp= bp;    Derived d;    d.m=1;std::cout<< d.*dp<<' '<< d.*bp<<'\n';// prints 1 1}

      Conversion in the opposite direction, from a pointer to data member of a derived class to a pointer to data member of an unambiguous non-virtual base class, is allowed withstatic_cast andexplicit cast, even if the base class does not have that member (but the most-derived class does, when the pointer is used for access):

      struct Base{};struct Derived: Base{int m;}; int main(){int Derived::* dp=&Derived::m;int Base::* bp=static_cast<int Base::*>(dp);     Derived d;    d.m=7;std::cout<< d.*bp<<'\n';// okay: prints 7     Base b;std::cout<< b.*bp<<'\n';// undefined behavior}

      The pointed-to type of a pointer-to-member may be a pointer-to-member itself: pointers to members can be multilevel, and can be cv-qualified differently at every level. Mixed multi-level combinations of pointers and pointers-to-members are also allowed:

      struct A{int m;// const pointer to non-const memberint A::*const p;}; int main(){// non-const pointer to data member which is a const pointer to non-const memberint A::*const A::* p1=&A::p; const A a={1,&A::m};std::cout<< a.*(a.*p1)<<'\n';// prints 1 // regular non-const pointer to a const pointer-to-memberint A::*const* p2=&a.p;std::cout<< a.**p2<<'\n';// prints 1}

      [edit]Pointers to member functions

      A pointer to non-static member functionf which is a member of classC can be initialized with the expression&C::f exactly. Expressions such as&(C::f) or&f insideC's member function do not form pointers to member functions.

      Such a pointer may be used as the right-hand operand of thepointer-to-member access operatorsoperator.* andoperator->*. Theresulting expression can be used only as the left-hand operand of a function-call operator:

      struct C{void f(int n){std::cout<< n<<'\n';}}; int main(){void(C::* p)(int)=&C::f;// pointer to member function f of class C    C c;(c.*p)(1);// prints 1    C* cp=&c;(cp->*p)(2);// prints 2}


      Pointer to member function of a base class can beimplicitly converted to pointer to the same member function of a derived class:

      struct Base{void f(int n){std::cout<< n<<'\n';}};struct Derived: Base{}; int main(){void(Base::* bp)(int)=&Base::f;void(Derived::* dp)(int)= bp;    Derived d;(d.*dp)(1);(d.*bp)(2);}

      Conversion in the opposite direction, from a pointer to member function of a derived class to a pointer to member function of an unambiguous non-virtual base class, is allowed withstatic_cast andexplicit cast, even if the base class does not have that member function (but the most-derived class does, when the pointer is used for access):

      struct Base{};struct Derived: Base{void f(int n){std::cout<< n<<'\n';}}; int main(){void(Derived::* dp)(int)=&Derived::f;void(Base::* bp)(int)=static_cast<void(Base::*)(int)>(dp);     Derived d;(d.*bp)(1);// okay: prints 1     Base b;(b.*bp)(2);// undefined behavior}

      Pointers to member functions may be used as callbacks or as function objects, often after applyingstd::mem_fn orstd::bind:

      Run this code
      #include <algorithm>#include <cstddef>#include <functional>#include <iostream>#include <string> int main(){std::vector<std::string> v={"a","ab","abc"};std::vector<std::size_t> l;    transform(v.begin(), v.end(),std::back_inserter(l),std::mem_fn(&std::string::size));for(std::size_t n: l)std::cout<< n<<' ';std::cout<<'\n';}

      Output:

      1 2 3

      [edit]Null pointers

      Pointers of every type have a special value known asnull pointer value of that type. A pointer whose value is null does not point to an object or a function (the behavior of dereferencing a null pointer is undefined), and compares equal to all pointers of the same type whose value is alsonull.

      Anull pointer constant can be used to initialize a pointer to null or to assign the null value to an existing pointer, it is one of the following values:

      • An integer literal with value zero.
      (since C++11)

      The macroNULL can also be used, it expands to an implementation-defined null pointer constant.

      Zero-initialization andvalue-initialization also initialize pointers to their null values.

      Null pointers can be used to indicate the absence of an object (e.g.std::function::target()), or as other error condition indicators (e.g.dynamic_cast). In general, a function that receives a pointer argument almost always needs to check if the value is null and handle that case differently (for example, thedelete expression does nothing when a null pointer is passed).

      [edit]Invalid pointers

      A pointer valuep isvalid in the context of an evaluatione if one of the following condition is satisfied:

      • p is a null pointer value.
      • p is a pointer to function.
      • p it is a pointer to or past the end of an objecto, ande is in the duration of the region of storage foro.

      If a pointer valuep is used in an evaluatione, andp is not valid in the context ofe, then:

      int* f(){int obj;int* local_ptr= new(&obj)int; *local_ptr=1;// OK, the evaluation “*local_ptr” is// in the storage duration of “obj” return local_ptr;} int* ptr= f();// the storage duration of “obj” is expired,// therefore “ptr” is an invalid pointer in the following contexts int* copy= ptr;// implementation-defined behavior*ptr=2;// undefined behavior: indirection of an invalid pointerdelete ptr;// undefined behavior: deallocating storage from an invalid pointer

      [edit]Constness

      • Ifcv appears before* in the pointer declaration, it is part of the declaration specifier sequence and applies to the pointed-to object.
      • Ifcv appears after* in the pointer declaration, it is part of thedeclarator and applies to the pointer that's being declared.
      Syntaxmeaning
      const T*pointer to constant object
      Tconst*pointer to constant object
      T*constconstant pointer to object
      const T*constconstant pointer to constant object
      Tconst*constconstant pointer to constant object
      // pc is a non-const pointer to const int// cpc is a const pointer to const int// ppc is a non-const pointer to non-const pointer to const intconstint ci=10,*pc=&ci,*const cpc= pc,**ppc;// p is a non-const pointer to non-const int// cp is a const pointer to non-const intint i,*p,*const cp=&i; i= ci;// okay: value of const int copied into non-const int*cp= ci;// okay: non-const int (pointed-to by const pointer) can be changedpc++;// okay: non-const pointer (to const int) can be changedpc= cpc;// okay: non-const pointer (to const int) can be changedpc= p;// okay: non-const pointer (to const int) can be changedppc=&pc;// okay: address of pointer to const int is pointer to pointer to const int ci=1;// error: const int cannot be changedci++;// error: const int cannot be changed*pc=2;// error: pointed-to const int cannot be changedcp=&ci;// error: const pointer (to non-const int) cannot be changedcpc++;// error: const pointer (to const int) cannot be changedp= pc;// error: pointer to non-const int cannot point to const intppc=&p;// error: pointer to pointer to const int cannot point to// pointer to non-const int

      In general, implicit conversion from one multi-level pointer to another follows the rules described inqualification conversions.

      [edit]Composite pointer type

      When an operand of acomparison operator or any of the second and third operands of aconditional operator is a pointer or pointer-to-member, a composite pointer type is determined to be the common type of these operands.

      Given two operandsp1 andp2 having typesT1 andT2, respectively,p1 andp2 can only have a composite pointer type if any of the following conditions are satisfied:

      • p1 andp2 are both pointers.
      • One ofp1 andp2 is a pointer and the other operand is a null pointer constant.
      • p1 andp2 are both null pointer constants, and at least one ofT1 andT2 is a non-integral type.
      (since C++11)
      (until C++14)
      • At least one ofT1 andT2 is a pointer type, pointer-to-member type orstd::nullptr_t.
      (since C++14)

      Thecomposite pointer typeC ofp1 andp2 is determined as follows:

      (until C++11)
      (since C++11)
      • Otherwise, if all following conditions are satisfied:
      • T1 orT2 is “pointer tocv1void”.
      • The other type is “pointer tocv2T”, whereT is anobject type orvoid.
      C is “pointer tocv12void”, wherecv12 is the union ofcv1 andcv2.
      • Otherwise, if all following conditions are satisfied:
      • T1 orT2 is “pointer to function typeF1”.
      • The other type is “pointer to noexcept function typeF2”.
      • F1 andF2 are the same except noexcept.
      C is “pointer toF1”.
      (since C++17)
      • Otherwise, if all following conditions are satisfied:
      • T1 is “pointer toC1”.
      • T2 is “pointer toC2”.
      • One ofC1 andC2 isreference-related to the other.
      C is
      • thequalification-combined type ofT1 andT2, ifC1 is reference-related toC2, or
      • the qualification-combined type ofT2 andT1, ifC2 is reference-related toC1.
      • Otherwise, if all following conditions are satisfied:
      • T1 orT2 is “pointer to member ofC1 of function typeF1”.
      • The other type is “pointer to member ofC2 of noexcept function typeF2”.
      • One ofC1 andC2 is reference-related to the other.
      • F1 andF2 are the same except noexcept.
      C is
      • “pointer to member ofC2 of typeF1”, ifC1 is reference-related toC2, or
      • “pointer to member ofC1 of typeF1”, ifC2 is reference-related toC1.
      (since C++17)
      • Otherwise, if all following conditions are satisfied:
      • T1 is “pointer to member ofC1 of non-function typeM1”.
      • T2 is “pointer to member ofC2 of non-function typeM2
      • M1 andM2 are the same except top-level cv-qualifications.
      • One ofC1 andC2 is reference-related to the other.
      C is
      • the qualification-combined type ofT2 andT1, ifC1 is reference-related toC2, or
      • the qualification-combined type ofT1 andT2, ifC2 is reference-related toC1.
      • Otherwise, ifT1 andT2 aresimilar types,C is the qualification-combined type ofT1 andT2.
      • Otherwise,p1 andp2 do not have a composite pointer type, a program that necessitates the determination ofC such a type is ill-formed.
      using p=void*;using q=constint*;// The determination of the composite pointer type of “p” and “q”// falls into the [“pointer to cv1 void” and “pointer to cv2 T”] case:// cv1 = empty, cv2 = const, cv12 = const// substitute “cv12 = const” into “pointer to cv12 void”:// the composite pointer type is “const void*” using pi=int**;using pci=constint**;// The determination of the composite pointer type of “pi” and “pci”// falls into the [pointers to similar types “C1” and “C2”] case:// C1 = int*, C2 = const int*// they are reference-related types (in both direction) because they are similar// the composite pointer type is the qualification-combined type// of “p1” and “pc1” (or that of “pci” and “pi”): “const int**”

      [edit]Defect reports

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

      DRApplied toBehavior as publishedCorrect behavior
      CWG 73C++98a pointer to an object never compares equal
      to a pointer to one past the end of an array
      for non-null and non-function pointers,
      compare the addresses they represent
      CWG 903C++98any integral constant expression that
      evaluates to 0 was a null pointer constant
      limited to integer
      literals with value 0
      CWG 1438C++98the behavior of using an invalid pointer
      value in any way was undefined
      behaviors other than indirection and
      passing to deallocation functions
      are implementation-defined
      CWG 1512
      (N3624)
      C++98the rule of composite pointer type was incomplete, and thus
      did not allow comparison betweenint** andconstint**
      made complete
      CWG 2206C++98a pointer tovoid and a pointer to
      function had a composite pointer type
      they do not have such a type
      CWG 2381C++17function pointer conversions were not allowed
      when determining the composite pointer type
      allowed
      CWG 2822C++98reaching the end of the duration of a region
      of storage could invalidate pointer values
      pointer validity is based
      on the evaluation context
      CWG 2933C++98pointers to functions were always invalidthey are always valid

      [edit]See also

      C documentation forPointer declaration
      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/pointer&oldid=183327"

      [8]ページ先頭

      ©2009-2025 Movatter.jp