Difference between revisions of "cpp/language/this"
m (expand on what's after cv-qual) |
m (default member initializer) |
||
Line 10: | Line 10: | ||
@1@ Within the body of any non-static {{rlp|member functions|member function}}, including {{rlp|initializer list|member initializer list}} | @1@ Within the body of any non-static {{rlp|member functions|member function}}, including {{rlp|initializer list|member initializer list}} | ||
@2@ within the {{rlp|function|declaration}} of a non-static member function anywhere after the (optional) cv-qualifier sequence, including {{rlp|except_spec|dynamic exception specification}}{{mark deprecated}}, {{rlp|noexcept_spec|noexcept specification}}{{mark c++11}}, and the trailing return type{{mark since c++11}} | @2@ within the {{rlp|function|declaration}} of a non-static member function anywhere after the (optional) cv-qualifier sequence, including {{rlp|except_spec|dynamic exception specification}}{{mark deprecated}}, {{rlp|noexcept_spec|noexcept specification}}{{mark c++11}}, and the trailing return type{{mark since c++11}} | ||
− | @3@ within {{rlp|data_members#Member_initialization| | + | @3@ within {{rlp|data_members#Member_initialization|default member initializer}} {{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. | ||
− | When a non-static class member is used in any of the contexts where the {{tt|this}} keyword is allowed (non-static member function bodies, member initializer lists, | + | When a non-static class member is used in any of the contexts where the {{tt|this}} keyword is allowed (non-static member function bodies, member initializer lists, default member initializers), the implicit {{ttb|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, {{tt|this}} is a {{rlp|dependent name|dependent expression}}, and explicit {{tt|this->}} may be used to force another expression to become dependent. | In class templates, {{tt|this}} is a {{rlp|dependent name|dependent expression}}, and explicit {{tt|this->}} may be used to force another expression to become dependent. | ||
Line 57: | Line 57: | ||
class Outer { | class Outer { | ||
int a[sizeof(*this)]; // error: not inside a member function | int a[sizeof(*this)]; // error: not inside a member function | ||
− | unsigned int sz = sizeof(*this); // OK: in | + | unsigned int sz = sizeof(*this); // OK: in default member initializer |
void f() { | void f() { | ||
int b[sizeof(*this)]; // OK | int b[sizeof(*this)]; // OK |
Revision as of 12:14, 20 October 2015
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, default member 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: after delete this; returns, 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 is used, for example, in the member function of the control block of std::shared_ptr responsible for decrementing the reference count, 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 default member 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; }