Namespaces
Variants
Views
Actions

Difference between revisions of "cpp/language/this"

From cppreference.com
< cpp‎ | language
m (wording)
(+use in trailing return types and the example from 5.1.1)
Line 7: Line 7:
 
{{sdsc end}}
 
{{sdsc end}}
  
Within the body of any non-static {{rlp|member functions|member function}}, including {{rlp|initializer list|member initializer list}} and within brace-or-equal initializers of class members, the keyword {{tt|this}} is a {{rlp|value_category|prvalue}} {{rlp|expressions|expression}} whose value is the address of the object, on which the member function is being called.
+
The keyword {{tt|this}} is a {{rlp|value_category|prvalue}} {{rlp|expressions|expression}} whose value is the address of the object, on which the member function is being called. It can appear in the following contexts:
 +
@1@ Within the body of any non-static {{rlp|member functions|member function}}, including {{rlp|initializer list|member initializer list}}
 +
@2@ within the declaration of a non-static member function anywhere after the (optional) cv-qualifier sequence, including the trailing return type, if used
 +
@2@ within {{rlp|data_members#Member_initialization|brace-or-equal initializer}} of a non-static data member {{mark since c++11}}
  
 
The type of {{tt|this}} in a member function of class {{tt|X}} is {{tt|X*}} (pointer to X). If the member function is {{rlp|member_functions|cv-qualified}}, the type of {{tt|this}} is {{tt|cv X*}} (pointer to identically cv-qualified X). Since constructors and destructors cannot be cv-qualified, the type of {{tt|this}} in them is always {{tt|X*}}, even when constructing or destroying a const object.
 
The type of {{tt|this}} in a member function of class {{tt|X}} is {{tt|X*}} (pointer to X). If the member function is {{rlp|member_functions|cv-qualified}}, the type of {{tt|this}} is {{tt|cv X*}} (pointer to identically cv-qualified X). Since constructors and destructors cannot be cv-qualified, the type of {{tt|this}} in them is always {{tt|X*}}, even when constructing or destroying a const object.
Line 52: Line 55:
 
};
 
};
  
 +
class Outer {
 +
    int a[sizeof(*this)]; // error: not inside a member function
 +
    unsigned int sz = sizeof(*this); // OK: in brace-or-equal-initializer
 +
    void f() {
 +
        int b[sizeof(*this)]; // OK
 +
        struct Inner {
 +
            int c[sizeof(*this)]; // error: not inside a member function of Inner
 +
        };
 +
    }
 +
}
 
int main()
 
int main()
 
{
 
{

Revision as of 15:42, 30 May 2014

 
 
C++ language
General topics
Flow control
Conditional execution statements
if
Iteration statements (loops)
for
range-for (C++11)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications (until C++17*)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
const/volatile
decltype (C++11)
auto (C++11)
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
explicit (C++11)
static

Special member functions
Templates
Miscellaneous
 
 

Syntax

this

The keyword this is a prvalue expression whose value is the address of the object, on which the member function is being called. It can appear in the following contexts:

1) Within the body of any non-static member function, including member initializer list
2) within the declaration of a non-static member function anywhere after the (optional) cv-qualifier sequence, including the trailing return type, if used
2) within brace-or-equal initializer of a non-static data member (since C++11)

The type of this in a member function of class X is X* (pointer to X). If the member function is cv-qualified, the type of this is cv X* (pointer to identically cv-qualified X). Since constructors and destructors cannot be cv-qualified, the type of this in them is always X*, even when constructing or destroying a const object.

When a non-static class member is used in any of the contexts where the this keyword is allowed (non-static member function bodies, member initializer lists, in-class brace-or-equal initializers), the implicit this-> is automatically added before the name, resulting in a member access expression (which, if the member is a virtual member function, results in a virtual function call).

In class templates, this is a dependent expression, and explicit this-> may be used to force another expression to become dependent.

It is possible to execute delete this;, if the program can guarantee that the object was allocated by new, however, this renders every pointer to the deallocated object invalid, including the this pointer itself: such member function cannot refer to a member of a class (since this involves an implicit dereference of this) and no other member function may be called (this effectively limits the use of delete this; to destructors). This is used, for example, in the destructor of the control block of std::shared_ptr when the last reference to the managed object goes out of scope.

Example

class T
{
    int x;
 
    void foo()
    {
        x = 6;       // same as this->x = 6;
        this->x = 5; // explicit use of this->
    }
 
    void foo() const
    {
//        x = 7; // Error: *this is constant
    }
 
    void foo(int x) // parameter x shadows the member with the same name
    {
        this->x = x; // unqualified x refers to the parameter
                     // 'this->' required for disambiguation
    }
 
    int y;
    T(int x) : x(x), // uses parameter x to initialize member x
               y(this->x) // uses member x to initialize member y
    {}
 
    T& operator= ( const T& b )
    {
        x = b.x;
        return *this; // many overloaded operators return *this
    }
};
 
class Outer {
    int a[sizeof(*this)]; // error: not inside a member function
    unsigned int sz = sizeof(*this); // OK: in brace-or-equal-initializer
    void f() {
        int b[sizeof(*this)]; // OK
        struct Inner {
            int c[sizeof(*this)]; // error: not inside a member function of Inner
        };
    }
}
int main()
{
    T t;
}