This question already has answers here:
When should I make explicit use of the `this` pointer?
(12 answers)
Closed 6 years ago.
What is purpose of this keyword. Doesn't the methods in a class have access to other peer members in the same class ? What is the need to call a this to call peer methods inside a class?
Two main uses:
To pass *this or this as a parameter to other, non-class methods.
void do_something_to_a_foo(Foo *foo_instance);
void Foo::DoSomething()
{
do_something_to_a_foo(this);
}
To allow you to remove ambiguities between member variables and function parameters. This is common in constructors.
MessageBox::MessageBox(const string& message)
{
this->message = message;
}
(Although an initialization list is usually preferable to assignment in this particular example.)
Helps in disambiguating variables.
Pass yourself as a parameter or return yourself as a result
Example:
struct A
{
void test(int x)
{
this->x = x; // Disambiguate. Show shadowed variable.
}
A& operator=(A const& copy)
{
x = copy.x;
return *this; // return a reference to self
}
bool operator==(A const& rhs) const
{
return isEqual(*this, rhs); // Pass yourself as parameter.
// Bad example but you can see what I mean.
}
private:
int x;
};
Consider the case when a parameter has the same name as a class member:
void setData(int data){
this->data = data;
}
Resolve ambgiguity between member variables/functions and those defined at other scopes
Make explicit to a reader of the code that a member function is being called or a member variable is being referenced.
Trigger IntelliSense in the IDE (though that may just be me).
The expression *this is commonly used to return the current object from a member function:
return *this;
The this pointer is also used to guard against self-reference:
if (&Object != this) {
// do not execute in cases of self-reference
It lets you pass the current object to another function:
class Foo;
void FooHandler(Foo *foo);
class Foo
{
HandleThis()
{
FooHandler(this);
}
};
Some points to be kept in mind
This pointer stores the address of
the class instance, to enable pointer
access of the members to the member
functions of the class.
This pointer is not counted for
calculating the size of the object.
This pointers are not accessible for
static member functions.
This pointers are not modifiable
Look at the following example to understand how to use the 'this' pointer explained in this C++ Tutorial.
class this_pointer_example // class for explaining C++ tutorial
{
int data1;
public:
//Function using this pointer for C++ Tutorial
int getdata()
{
return this->data1;
}
//Function without using this pointer
void setdata(int newval)
{
data1 = newval;
}
};
Thus, a member function can gain the access of data member by either using this pointer or not.
Also read this to understand some other basic things about this pointer
It allows you to get around members being shadowed by method arguments or local variables.
The this pointer inside a class is a reference to itself. It's needed for example in this case:
class YourClass
{
private:
int number;
public:
YourClass(int number)
{
this->number = number;
}
}
(while this would have been better done with an initialization list, this serves for demonstration)
In this case you have 2 variables with the same name
The class private "number"
And constructor parameter "number"
Using this->number, you let the compiler know you're assigning to the class-private variable.
For example if you write an operator=() you must check for self assignment.
class C {
public:
const C& operator=(const C& rhs)
{
if(this==&rhs) // <-- check for self assignment before anything
return *this;
// algorithm of assignment here
return *this; // <- return a reference to yourself
}
};
The this pointer is a way to access the current instance of particular object. It can be used for several purposes:
as instance identity representation (for example in comparison to other instances)
for data members vs. local variables disambiguation
to pass the current instance to external objects
to cast the current instance to different type
One more purpose is to chaining object:
Consider the following class:
class Calc{
private:
int m_value;
public:
Calc() { m_value = 0; }
void add(int value) { m_value += value; }
void sub(int value) { m_value -= value; }
void mult(int value) { m_value *= value; }
int getValue() { return m_value; }
};
If you wanted to add 5, subtract 3, and multiply by 4, you’d have to do this:
#include
int main()
{
Calc calc;
calc.add(5); // returns void
calc.sub(3); // returns void
calc.mult(4); // returns void
std::cout << calc.getValue() << '\n';
return 0;
}
However, if we make each function return *this, we can chain the calls together. Here is the new version of Calc with “chainable” functions:
class Calc
{
private:
int m_value;
public:
Calc() { m_value = 0; }
Calc& add(int value) { m_value += value; return *this; }
Calc& sub(int value) { m_value -= value; return *this; }
Calc& mult(int value) { m_value *= value; return *this; }
int getValue() { return m_value; }
};
Note that add(), sub() and mult() are now returning *this. Consequently, this allows us to do the following:
#include <iostream>
int main()
{
Calc calc;
calc.add(5).sub(3).mult(4);
std::cout << calc.getValue() << '\n';
return 0;
}
We have effectively condensed three lines into one expression.
Copied from :http://www.learncpp.com/cpp-tutorial/8-8-the-hidden-this-pointer/
Sometimes you want to directly have a reference to the current object, in order to pass it along to other methods or to store it for later use.
In addition, method calls always take place against an object. When you call a method within another method in the current object, is is equivalent to writing this->methodName()
You can also use this to access a member rather than a variable or argument name that "hides" it, but it is (IMHO) bad practice to hide a name. For instance:
void C::setX(int x)
{
this->x = x;
}
For clarity, or to resolve ambiguity when a local variable or parameter has the same name as a member variable.
It also allows you to test for self assignment in assignment operator overloads:
Object & operator=(const Object & rhs) {
if (&rhs != this) {
// do assignment
}
return *this;
}
It also allows objects to delete themselves. This is used in smart pointers implementation, COM programming and (I think) XPCOM.
The code looks like this (excerpt from some larger code):
class counted_ptr
{
private:
counted_ptr(const counted_ptr&);
void operator =(const counted_ptr&);
raw_ptr_type _ptr;
volatile unsigned int _refcount;
delete_function _deleter;
public:
counted_ptr(raw_ptr_type const ptr, delete_function deleter)
: _ptr(ptr), _refcount(1), _deleter(deleter) {}
~counted_ptr() { (*_deleter)(_ptr); }
unsigned int addref() { return ++_refcount; }
unsigned int release()
{
unsigned int retval = --_refcount;
if(0 == retval)
>>>>>>>> delete this;
return retval;
}
raw_ptr_type get() { return _ptr; }
};
The double colon in c++ is technically known as "Unary Scope resolution operator".
Basically it is used when we have the same variable repeated for example inside our "main" function (where our variable will be called local variable) and outside main (where the variable is called a global variable).
C++ will alwaysexecute the inner variable ( that is the local one).
So imagine you want to use the global variable "Conundrum" instead the local one just because the global one is expressed as a float instead of as an integer:
#include <iostream>
using namespace std;
float Conundrum=.75;
int main()
{
int Conundrum =75;
cout<<::Conundrum;
}
So in this case the program will use our float Conundrum instead of the int Conundrum.
Related
Suppose I have a class that has an array of pointers, and I have a method that dereferences a pointer and returns it as a reference. I want to allow the method caller to call non-const methods of the object the pointer is pointing to, but also want to protect myself from the caller changing what the pointer is pointing to. If I return a const reference, I have to mark many of the pointer object's methods as const, and hence many of its class member variables as mutable.
Is this bad practice? If so, how do I get around this?
Is there performance penalty for over-using mutable?
Example:
#include <iostream>
#include <array>
#include <memory>
class Counter
{
public:
Counter();
void hit() const;
void reset();
unsigned count() const;
private:
mutable unsigned count_;
};
Counter::Counter() : count_(0) {}
void Counter::hit() const { ++count_; }
void Counter::reset() { count_ = 0; }
unsigned Counter::count() const { return count_; }
class CircularArray
{
public:
CircularArray();
const Counter& next() const;
private:
mutable unsigned i_;
std::array<std::unique_ptr<Counter>, 3> arr_;
};
CircularArray::CircularArray() : i_(2)
{
arr_[0] = std::unique_ptr<Counter>(new Counter);
arr_[1] = std::unique_ptr<Counter>(new Counter);
arr_[2] = std::unique_ptr<Counter>(new Counter);
}
const Counter& CircularArray::next() const { return *arr_[(i_ = (i_ + 1) % 3)]; }
int main()
{
CircularArray circular;
const Counter* p;
p = &circular.next();
p->hit();
p->hit();
Counter c;
//*p = c; // <-- Want to prevent this
}
To extend what I was saying, there is no point in abusing mutable for this. If this is all you want to prevent:
*p = /* ... */;
then it can be done much more easily by deleting the assignment operator of Counter:
class Counter
{
void operator=(const Counter&) = delete;
// ...
};
Remember that the assignment operator does not affect the identity of the object: it doesn't change its address. Semantically, an assignment involving of modifying this object to replicate the state of another object. In fact, even if you forbid me from using the assignment operator somehow, I could still do this:
// a very inefficient way of performing `*p = c`
p->reset();
while (p->count() != c.count())
p->hit();
This achieves the exact same result as performing an assignment, albeit very clumsily and inefficiently.
Performing an assignment is no different than calling a non-const member function that accepts a single argument of type const Counter&. Hypothetically, you could redefine the assignment operator to do absolutely nothing at all if you wanted to (it would be a bad idea though).
I'm having a problem with correctly building a container that stores class specimens of different types that are all inheritors of a single abstract class. The register(the container) stores a pointer to the array of these specimens, that has the type of the abstract class. Whenever I try to access data contained in the specimens I only succeed in retrieving parts that can be found in the base class too. For example, an overloaded << used on the register that contains elements of all three inheritors, will only write the abstract class parts on screen, and will neglect anything not present there. Now I don't really know if the problem is with printing out the otherwise correctly stored elements, or the storing is already done in an inappropriate form, so that would be my question: how should this be done properly? Here's the code:
class Register{
private:
int elementNum;
type * pData;
friend std::ostream &operator<<(std::ostream & os,const Register &v);
};
class type{
int a;
int b;
};
class type2: public type{
int c;
int d;
};
The other two inheritors behave the same way as the type2. Here's a part of main:
int main ()
{
type2 A1(1,2,3,4);
type3 D1(4,5,6,7,8);
type4 H1(9,10,11,12,13);
std::cout<<A1<<D1<<H1<<endl;
Register R1;
R1.Add(0,A1);
R1.Add(1,D1);
R1.Add(2,H1);
R1.Display();
R1.MaxLength();
std::cout<<R1;
return 0;
}
Operator << on the register:
std::ostream &operator<<(std::ostream & os,const Register &v){
for(int i=0;i<v.elementNum;i++)
{
os<<v.pData[i]<<endl;
}
return os;
}
Only using the << operator or a function from the register ends in this problem.
Edit: Implementation of the Add function:
void Register::Add(int position,type& T){
if(position<0||position>elementNum+1)
return;
type *pTemp = new type[elementNum+1];
if(elementNum==0)
{
pTemp[0]=T;
delete[]pData;
pData=pTemp;
}
else
{
for(int i=0,j=0;j<elementNum+1;i++,j++)
{
if(position!=j)
pTemp[j]=pData[i];
else
{
i--;
pTemp[j]=a;
}
}
delete[]pData;
pData=pTemp;
}
elementNum++;
}
You can only access public members common to the base class, or virtual method available from the base, polymorphically.
Furthermore, you can only access virtual methods through pointers/references, and you generally can't store different class instances contiguously like you try to do with pData.
If you make a virtual std::ostream &type::dump(std::ostream &os) member method and override is in type2, etc., you can make each overriddinen method show content particular to its sub-type.
struct type {
virtual ostream &dump(ostream &os) {
os << a << " " << b << " ";
return os;
}
int a;
int b;
};
struct type2 : type {
// Can use parent implementation AND use subtype-specific members:
ostream &dump(ostream &os) override {
type::dump(os);
os << c << " " << d << " ";
return os;
}
int c;
int d;
};
// This class needs new "void Add(int pos, type &)" logic.
struct Register {
int elementNum;
type *pData; // next hint: this is almost definitely not what you want.
type **pda; // probably better (need to use new/delete to make types)
};
ostream &operator<<(ostream &os, Register const &v) {
for (int i = 0; i < v.elementNum; ++i) {
// Calls proper virtual method for each instance.
v.pData[i].dump(os); // XXX probably broken too
v.pda[i]->dump(os); // should look more like this
os << endl;
}
}
type *pTemp = new type[elementNum+1];
This allocates an array of objects with type type. An object can never change its type, and you cannot replace an element of an array, only modify it. So your Register object never contains objects of any derived classes at all, only those objects with the base class type.
To get an array of heterogeneous objects the hard way, you would need an array of pointers:
type **pTemp = new (type*[elementNum+1]);
To do it the right way, you would shun arrays and raw pointers, and instead use containers and smart pointers:
class Register {
public:
const type& get(int pos) const;
type& get(int pos);
void Add(int pos, const type& obj);
void Add(int pos, std::unique_ptr<type>&& ptr);
// ...
private:
std::vector<std::unique_ptr<type>> m_data;
};
But either way, what pointers do you put in it from your function Add?
void Register::Add(int position,type& T);
Probably not the address &T of the passed reference. Who knows when that object will be destructed. And new type(T) is no good either - it just creates an object of the base type, ignoring the actual type of T. So you'll probably want a clone() method, sometimes called a "virtual copy constructor":
class type {
public:
using pointer = std::unique_ptr<type>;
virtual ~type();
virtual pointer clone() const;
};
type::pointer type::clone() const {
return pointer(new type(*this));
}
type::pointer type2::clone() const {
return pointer(new type2(*this));
}
Above I put in two overloads of Add(). The object-passing version goes like:
void Register::Add(int pos, const type& obj) {
if (pos<0)
return;
if (pos >= m_data.size())
m_data.resize(pos+1);
m_data[pos] = obj.clone();
}
The other version could be useful if you happen to have a type::pointer already, rather than just an object. With this overload you can just move it into the Register, without needing to clone() anything.
void Register::Add(int pos, type::pointer&& ptr) {
if (pos<0)
return;
if (pos >= m_data.size())
m_data.resize(pos+1);
m_data[pos] = std::move(ptr);
}
in the code below, it does not matter whether i put "this->" or remove it. it gives same output and result in both cases.
So, what is the point of having the "this" pointer in C++? Are there other usages where it is essential?
Thanks.
#include<iostream>
using namespace std;
class square{
int l;
int w;
public:
square(int x, int y){
w = x;
l = y;
}
int getArea(){
return w * l;
};
bool AreaSmallerThan(square c){
if(this->getArea() < c.getArea())
return true;
else
return false;
}
};
int main(){
square A(2,3);
square B(1,3);
if(A.AreaSmallerThan(B))
cout<<"A is smaller than B."<<endl;
else
cout<<"A is NOT smaller than B."<<endl;
return 0;
}
TL;DR: It has it's uses. If you choose good naming practices, you generally won't need to use it often.
There are a number of cases where you would want a "pointer to the current object", for example:
struct Foo
{
void MakeCallback(eventid_t eventId)
{
scheduleCallback(eventId, callbackProxyFn, this);
}
static void callbackProxyFn(eventid_t eventId, Foo* foo)
{
// call 'callback' on the relevant object instance.
foo->callback(eventId);
}
void callback(eventid_t eventId);
};
It can also be used to resolve conflicts between names in the current object and other scopes, if you choose to use terrible naming conventions.
void Foo::bar(int n)
{
this->n = n;
}
You could avoid this (pun intended) scenario, as is common practice, by prefixing statics, globals and members:
class Player {
int m_score;
public:
Player(int score) : m_score(score) {}
};
Player g_player1;
static Player s_login; // yeah, I know, terrible, just an example tho.
A common use is in eliminating self in copy/comparison operators:
bool Foo::operator==(const Foo& rhs) const
{
if (this == &rhs)
return true;
...
}
You can also use it to produce a reference to the current object:
foo(const Foo&);
void foo(*this);
Yes there are times it is essential. A classic case is in operator=, to avoid destroying resources during self-assignment.
for example https://stackoverflow.com/a/3975092/103167
Set& Set::operator=(const Set& setEqual)
{
//first check for self assignment
if (&setEqual == this)
cout << "this is self assignment";
return *this;
}
(Note that this isn't needed when using the copy-and-swap idiom)
Accessing members via this is also frequently seen in template code which inherits from a template parameter. Those inherited names can only be found during second phase lookup, which means they need to be qualified with this->
Random example...what if you had passed an int w, int l into your getArea() function...then you need to use the this keyword to differentiate between the local parameter
int getArea(int w, int l){
return this->w * this->l;
};
Another common example might be move assignment. I have pasted an example from a Tree datastructure project I coded.
/* move assignment */
TreeSet& operator= (TreeSet&& rhs)
{
clearAll(rootPtr);
this->rootPtr = rhs.rootPtr;
rhs.rootPtr = nullptr;
return *this;
}
And finally another example for an iterator I wrote...when overloading the ++ operator on an iterator, you want to return the resulting iterator..
/* Update the current pointer to advance to the node
* with the next larger value
*/
const_iterator& operator++ () {
//I have deleted all the logic for the sake of not taking up a ton of space..
return *this;
}
Generally speaking, the 'this' pointer can be useful when an instance of a class is invoking some method and the instance itself needs to be passed from within the method to some function outside of the class.
I've the following utility function to convert a given string to integer.
class convertToInt:public std::unary_function<const char*, int>
{
public:
int operator()(const char* cNumber)
{
try
{
int result = boost::lexical_cast<int>(cNumber);
return result;
} catch ( boost::bad_lexical_cast& error)
{
std::cerr << "Error in converting to number "<< error.what() << std::endl;
return -1;
}
}
};
When I want to actually use this utility function, I've to do the following.
convertToInt cStrToInt;
int iNumberToCheck = cStrToInt(argv[1]);
I'm just wondering, is there a way, I can directly call
int iNumberToCheck = convertToInt(argv[1]);
No, it is a member function and requires an object for it to be invoked on. You could use an unnamed temporary instead:
int iNumberToCheck = convertToInt()(argv[1]);
You can make the function static, so that it does not require an instance. The call has to be scoped.
You can also create the temporary as part of your larger expression (rather than using a named variable), which may seem less efficient but in practice is probably optimized to the same thing by your compiler.
Edit to add: static won't work for operator(), so you would need to rework to use that option.
If you know the name of the functor at the call-site, then you why not just turn it into a function?
int convertToInt(const char* cNumber)
{
/*...*/
}
int iNumberToCheck = convertToInt(argv[1]);
Just create a statically-initialized global variable, which helps avoid the static initialization order fiasco. Static initialization requires the class to be an aggregate type. Just use the braces to initialize it:
struct convertToIntF
{
int operator()(const char* cNumber) const
{
try
{
int result = boost::lexical_cast<int>(cNumber);
return result;
}
catch ( boost::bad_lexical_cast& error)
{
std::cerr << "Error in converting to number "<< error.what() << std::endl;
return -1;
}
}
};
convetToIntF converToInt = {};
Now, if the function object stores state or inherits from a class that is not an aggregate, this won't work. However, in C++11, its fairly trivial to write an adaptor that can static initialize any default constructible function object:
template<class F>
struct static_
{
template<class... T>
auto operator()(T && ... x) const -> decltype(F()(std::forward<T>(x)...))
{
static F f;
return f(std::forward<T>(x)...);
}
};
Then it can be initialized like this:
static_<convetToIntF> converToInt = {};
In this very simple case, an anonymous object will probably work fine, as others have pointed out. If you have a more complex class with state, however, consider the singleton pattern:
class SingletonFunctor
{
private:
// some private state
// for a hybrid approach, the constructor could be public
SingletonFunctor()
{
// initialize state
}
public:
static const SingletonFunctor& GetSingleton()
{
static const SingletonFunctor _singleton;
return _singleton;
}
SomeType operator() (SomeOtherType param) const
{
// do something interesting
}
};
int main (void)
{
SomeType firstVal = SingletonFunctor::GetSingleton()(SomeOtherType());
// ...
// later
// no need to instantiate another object
SomeType secondVal = SingletonFunctor::GetSingleton()(SomeOtherType());
}
Be careful with this pattern if you mutate state, it can then have all the same problems as a global variable (especially with multithreading).
In Java you can simply return this to get the current object. How do you do this in C++?
Java:
class MyClass {
MyClass example() {
return this;
}
}
Well, first off, you can't return anything from a void-returning function.
There are three ways to return something which provides access to the current object: by pointer, by reference, and by value.
class myclass {
public:
// Return by pointer needs const and non-const versions
myclass* ReturnPointerToCurrentObject() { return this; }
const myclass* ReturnPointerToCurrentObject() const { return this; }
// Return by reference needs const and non-const versions
myclass& ReturnReferenceToCurrentObject() { return *this; }
const myclass& ReturnReferenceToCurrentObject() const { return *this; }
// Return by value only needs one version.
myclass ReturnCopyOfCurrentObject() const { return *this; }
};
As indicated, each of the three ways returns the current object in slightly different form. Which one you use depends upon which form you need.
One of the main advantages of return by reference in classes is the ability to
easily chain functions.
Suppose that your member function is to multiply a particular member of your class.
If you make the header and source files to keep the information of the class and the definition of the member function separately, then,
the header file myclass.h would be:
#ifndef myclass_h
#define myclass_h
class myclass{
public:
int member1_;
double member2_;
myclass (){
member1_ = 1;
member2_ = 2.0;
}
myclass& MULT(int scalar);
myclass* MULTP(double scalar);
};
#endif
and the source file: myclass.cpp would be:
myclass& myclass::MULT(int scalar){
member1_ *= scalar;
return *this;
}
myclass* myclass::MULTP(double scalar){
member2_ *= scalar;
return this;
}
If you initialize an object called obj, the default constructor above sets member1_ equal to 1:
Then in your main function, you can do chains such as:
myclass obj;
obj.MULT(2).MULT(4);
Then member1_ would now be 8. Of course, the idea might be to chain different functions,
and alter different members.
In the case you are using the return by pointer, the first call uses the object,
and any subsequent call will treat the previous result as a pointer, thus
obj.MULTP(2.0)->MULTP(3.0);
Because the return type is void, i.e.: you declare that you don't return anything. Change it to myclass* to return this change to myclass & to return reference to the class through *this.