Difference between revisions of "cpp/language/this"
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}} | + | 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
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:
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; }