The use case of 'this' pointer in C++ - c++

I understand the meaning of 'this', but I can't see the use case of it.
For the following example, I should teach the compiler if the parameter is the same as member variable, and I need this pointer.
#include <iostream>
using namespace std;
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this->x = y
int getx() {return x;}
};
int main()
{
AAA a;
a.hello(10); // x <- 10
cout << a.getx();
a.hello2(20); // x <- 20
cout << a.getx();
}
What would be the use case for 'this' pointer other than this (contrived) example?
Added
Thanks for all the answers. Even though I make orangeoctopus' answer as accepted one, it's just because he got the most vote. I must say that all the answers are pretty useful, and give me better understanding.

Sometimes you want to return yourself from an operator, such as operator=
MyClass& operator=(const MyClass &rhs) {
// assign rhs into myself
return *this;
}

The 'this' pointer is useful if a method of the class needs to pass the instance (this) to another function.

It's useful if you need to pass a pointer to the current object to another function, or return it. The latter is used to allow stringing functions together:
Obj* Obj::addProperty(std::string str) {
// do stuff
return this;
}
obj->addProperty("foo")->addProperty("bar")->addProperty("baz");

In C++ it is not used very often. However, a very common use is for example in Qt, where you create a widget which has the current object as parent. For example, a window creates a button as its child:
QButton *button = new QButton(this);

When passing a reference to an object within one of its methods. For instance:
struct Event
{
EventProducer* source;
};
class SomeContrivedClass : public EventProducer
{
public:
void CreateEvent()
{
Event event;
event.source = this;
EventManager.ProcessEvent(event);
}
};

Besides obtaining a pointer to your own object to pass (or return) to other functions, and resolving that an identifier is a member even if it is hidden by a local variable, there is an really contrived usage to this in template programming. That use is converting a non-dependent name into a dependent name. Templates are verified in two passes, first before actual type substitution and then again after the type substitution.
If you declare a template class that derives from one of its type parameters you need to qualify access to the base class members so that the compiler bypasses the verification in the first pass and leaves the check for the second pass:
template <typename T>
struct test : T {
void f() {
// print(); // 1st pass Error, print is undefined
this->print(); // 1st pass Ok, print is dependent on T
}
};
struct printer {
void print() { std::cout << "print"; }
};
struct painter {
void paint() { std::cout << "paint"; }
};
int main() {
test<printer> t; // Instantiation, 2nd pass verifies that test<printer>::print is callable
t.f();
//test<painter> ouch; // 2nd pass error, test<painter>::print does not exist
}
The important bit is that since test inherits from T all references to this are dependent on the template argument T and as such the compiler assumes that it is correct and leaves the actual verification to the second stage. There are other solutions, like actually qualifying with the type that implements the method, as in:
template <typename T>
struct test2 : T {
void f() {
T::print(); // 1st pass Ok, print is dependent on T
}
};
But this can have the unwanted side effect that the compiler will statically dispatch the call to printer::print regardless of whether printer is a virtual method or not. So with printer::print being declared virtual, if a class derives from test<print> and implements print then that final overrider will be called, while if the same class derived from test2<print> the code would call printer::print.
// assumes printer::print is virtual
struct most_derived1 : test<printer> {
void print() { std::cout << "most derived"; }
};
struct most_derived2 : test2<printer> {
void print() { std::cout << "most derived"; }
};
int main() {
most_derived1 d1;
d1.f(); // "most derived"
most_derived2 d2;
d2.f(); // "print"
}

You can delete a dynamically created object by calling delete this from one of its member functions.

The this pointer is the pointer to the object itself. Consider for example the following method:
class AAA {
int x;
public:
int hello(int x) { some_method(this, x);}
};

void somefunc(AAA* a_p)
{
......
}
class AAA {
int x;
public:
int hello(int x) { this->x = x;}
int hello2(int y) {x = y;} // same as this.x = y
int getx() {return x;}
void DoSomething() { somefunc(this); }
};

this is implicit whenever you use a member function or variable without specifying it. Other than that, there are many, many situations in which you'll want to pass the current object to another function, or as a return value.
So, yeah, it's quite useful.

Sometimes you need to refer to "this" object itself, and sometimes you may need to disambiguate in cases where a local variable or a function parameter shadows a class member:
class Foo {
int i;
Foo* f() {
return this; // return the 'this' pointer
}
void g(){
j(this); // pass the 'this' pointer to some function j
}
void h(int i) {
this->i = i; // need to distinguish between class member 'i' and function parameter 'i'
}
};
The two first cases (f() and g() are the most meaningful cases. The third one could be avoided just by renaming the class member variable, but there's no way around using this in the first two cases.

Another possible use case of this:
#include <iostream>
using namespace std;
class A
{
public:
void foo()
{
cout << "foo() of A\n";
}
};
class B : A
{
public:
void foo()
{
((A *)this)->foo(); // Same as A::foo();
cout << "foo() of B\n";
}
};
int main()
{
B b;
b.foo();
return 0;
}
g++ this.cpp -o this
./this
foo() of A
foo() of B

One more use of this is to prevent crashes if a method is called on a method is called on a NULL pointer (similar to the NULL object pattern):
class Foo
{
public:
void Fn()
{
if (!this)
return;
...
}
};
...
void UseFoo(Foo* something)
{
something->Fn(); // will not crash if Foo == NULL
}
If this is useful or not depends on the context, but I've seen it occasionally and used it myself, too.

self-assignment protection

Related

Initialize member function arguments as data members in c++

When trying to implement a class like this
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(int base = /*the value of a*/){
// some function code
}
};
I want to initialize the argument base of the function fun with the value of a (the data member of the class).
Writing int base = a or int base = this->a doesn't work.
So, I thought I could overload the function this way.
void fun(void){
fun(a);
}
void fun(int base){
// some function code
}
This will actually work, but is there any better/smarter way to do the same thing? Because I have many other functions, I want to implement the same way. And I don't want to overload each of them.
Thanks.
You can make it explicit with std::optional. Before that (or Boost.Optional or whatever), the usual solution would be to sacrifice a magic value that base could never legally take (such as -1 in the other answer).
class sample{
int a_;
public:
sample(int a = 0) : a_(a) {}
void fun(std::optional<int> base = std::nullopt){
if (!base) base = a_;
// some function code
}
};
Or, as Jarod42 suggests, something like
void fun(std::optional<int> base_opt = std::nullopt){
int base = base_opt.value_or(a_);
// some function code
}
NB.
Writing int base = a or int base = this->a doesn't work
Yeah, there is no instance at the point where the function is declared, and that's when the default expression is evaluated.
I was under the impression that private members, when they're inaccessible at the call site, would be prohibited - but that isn't correct. So the expression must be evaluated when the function is declared, with the function's own access and symbol visibility at that point, even though it is executed at the call site.
Sentinel values
This can be achieved via a "sentinel" value. If a particular integer is unused (such as -1), try:
void fun(int base = -1) {
if (base == -1) {
base = this->a;
}
// ...
}
std::optional
Another way is to wrap the input up with an std::optional:
void fun(std::optional<int> base = std::nullopt) {
if (!base) {
base = this->a;
}
// Extract actual value by using *.
int base_value = *base;
// Use base_value.
// ...
}
In the example above, base_value is the "default"-corrected int that you desired. A more elegant alternative is to use std::optional<T>::value_or to extract the value:
void fun(std::optional<int> base = std::nullopt) {
int base_value = base.value_or(this->a);
// Use base_value.
// ...
}
Overload of fun is simple and clean:
class sample{
int a;
public:
sample(int a = 0){
this->a =a ;
}
void fun(){
fun(a);
}
void fun(int base){
// some function code
}
};

Calling a method inside a method of a different class C++

In my code, I have two classes. The first class has a private variable x. I'm trying to change its value by calling a method defined in a second class - setClass1X(). This method takes two parameters, the value that I want to set x to and an object of type class1. This method should call another method setX() of an object given as a parameter and pass it the value that i want to set x to. Then that method setX(), defined in the first class should set the value of x for that particular object. At the end program calls a function getX() from the first class and prints its return value. I always get 0 as an output because that is what constructor sets the value of x to, meaning that this approach does not work. Can you spot a mistake or tell my why this approach does not work. Thanks!
#include<iostream>
using namespace std;
class class1
{
private:
int x;
public:
class1()
{
x=0;
}
int getX()
{
return x;
}
void setX(int a)
{
x=a;
}
};
class class2
{
public:
void setClass1X(int n, class1 c)
{
c.setX(n);
}
};
int main()
{
class1 c1;
class2 c2;
c2.setClass1X(5, c1);
cout << c1.getX();
return 0;
}
As #MikeCAT has already pointed out a copy of class1 being pass and the changes made to the copy doesnt reflect into the original instance. So the solution is to pass the instance by reference.
However classes should be dependned on each other at the class level rather than at method level to mark clear dependnecy; unless you there is specific reason for not doing this.
class class2
{
private:
class1& c1;
public:
class2(class1& c)
: c1(c)
{
}
void setClass1X(int n)
{
c1.setX(n);
}
};
int main()
{
class1 c1;
class2 c2(c1);
c2.setClass1X(5);
cout << c1.getX();
return 0;
}
In Your setClass1X function, a copy of an object is passed to c1, so modification to that won't affect caller.
To have your functions modify what is passed, you should use references.
void setClass1X(int n, class1& c) // add "&"
{
c.setX(n);
}

Named Parameter Idiom using a pointer to a class private method

I got stuck with a C++ compilation error while doing something that is probably not really "conventional".
To make things easier I just re-wrote the mechanism I am trying to use in a easier-to-read way and I checked that I got the same issue.
First of all here is the code:
test.h // -- C++ --
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp;}
init() {}
virtual ~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
private:
funcPtr m_fp;
public:
item(init<MODULE> params) : m_fp(params.m_fp) {}
virtual ~item() {}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Method CB
int func1(int i);
// Item member
item<user> m_item;
public:
user();
virtual ~user();
};
test.cpp // -- C++ --
#include "test.h"
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {}
int user::func1(int i) {return 1;}
and here is the error:
/test.cpp:5:59: error: invalid use of non-static member function
user::user() : m_item(init<user>().has_funcPtr(this->func1) ) {
^
So, I am not sure this is the best way to achieve what I want (probably not, anyway if you have other suggestions they are very welcome) but my goal now is to make it work or to understand exactly why it can't work so that I learn something from it!
The basic idea is that:
the class "item" can be initialized with the named parameter idiom using the method "has_funcPtr" of the class "init" concatenated to its constructor like: "init().has_funcPtr(&function_name)".
the class "user" can store a pointer to its private method "func1" as a private member of its private member of type "item".
In this way, when a specific method of an object "item" is called (for simplicity I don't include this long part here since it is not relevant to the error but it is just to describe the goal of this snippet of code) that method can do stuff and call the private method of its father object "user" through that pointer to function (I hope this is clear enough...).
Now, I think there is an issue with the order of initialization of the objects but I am not sure where and how to fix it.
In particular I thought that since the "func1" method doesn't operate on any member of the class "user", then its reference could be used directly in the initialization list to initialize an "init" object and feed it to an "item" object.
Thank you all in advance
this->func1 doesn't form a member function pointer. It should look like &user::func1 if you are in the user class.
I post here the complete answer to my issue. I developed it after the suggestion from Bo and after understanding how to point to an instance specific method through a pointer to it.
In short, two things are really important to note:
A pointer to a non-static class member function could be thought at as just an offset rather than an "absolute address" (http://www.codeguru.com/cpp/cpp/article.php/c17401/C-Tutorial-PointertoMember-Function.htm). This means that you can't access that function (it is just an offset) without first having an instance pointer. Once you have the instance pointer, with this "offset pointer" you can call that method using:
(object_ptr->*method_ptr)(parameters_here)
A better way would be to use a #define macro since this syntax is really error prone and complex to read (https://isocpp.org/wiki/faq/pointers-to-members):
#define CALL_MEMBER_FN(ptrToObject,ptrToMember) ((ptrToObject)->*(ptrToMember))
and then use it as:
CALL_MEMBER_FN(object_ptr, method_ptr)(parameters_here)
Following the first point, if you want a nested class to be able to call the upper class method by a pointer to it, you also need to pass the upper class instance pointer to access that function. In my case, since I wanted to be able to decide case by case if that method should be called or not, I used the Named Parameter Idiom (below note that func2 is not registered for example).
Finally here is the revised code that it works (tested):
-- C++ -- test.h
#include <iostream>
template <typename MODULE> class item;
template <typename MODULE>
class init {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
init& has_funcPtr(funcPtr fp) { m_fp = fp; return *this;}
init& has_func2Ptr(func2Ptr fp2) { m_fp2 = fp2; return *this;}
init(MODULE* dad) : m_dad(dad) { std::cout << "init constructor called\n"; }
~init() {}
private:
friend class item<MODULE>;
};
template <typename MODULE>
class item {
public:
typedef int (MODULE::*funcPtr)(int);
typedef bool (MODULE::*func2Ptr)(bool);
private:
funcPtr m_fp;
func2Ptr m_fp2;
MODULE* m_dad;
public:
item(init<MODULE> params) :
m_fp(params.m_fp),
m_fp2(params.m_fp2),
m_dad(params.m_dad)
{
std::cout << "item constructor called\n";
}
~item() {}
// Method invoked externally
int callback() {
std::cout << "item class method callback invoked\n";
// In the real case here do general stuff
if(m_fp) {
int i = (m_dad->*m_fp)(1); // call member function through its pointer
return i;
} else {
std::cout << "callback not registered\n";
return 0;
}
}
// Method invoked externally
bool callback2() {
std::cout << "items class method callback2 invoked\n";
// In the real case here do general stuff
if(m_fp2) {
bool b = (m_dad->*m_fp2)(true); // call member function through its pointer
return b;
} else {
std::cout << "callback2 not registered\n";
return false;
}
}
};
class user {
public:
typedef init<user>::funcPtr funcPtr;
private:
// Methods that optionally add more functionalities to the 2 callbacks
int func1(int i);
bool func2(bool b);
public:
// Item member
item<user> m_item;
public:
user();
~user();
};
-- C++ -- test.cpp
#include "test.h"
user::user() : m_item(init<user>(this).has_funcPtr(&user::func1) ) {
std::cout << "user constructor called\n";
}
int user::func1(int i) {return i;}
bool user::func2(bool b) {return b;} // func2 won't be registered
int main() {
user* u = new user();
// Test callbacks
int i = u->m_item.callback();
bool b = u->m_item.callback2();
std::cout << "main is printing i=" << i << " and b=" << b << "\n";
std::cout << "expected results are i=1 and b=0\n" << "END\n";
return 0;
}
OUTPUT:
init constructor called
item constructor called
user constructor called
item class method callback invoked
items class method callback2 invoked
callback2 not registered
main is printing i=1 and b=0
expected results are i=1 and b=0
END

How to call a class member function recursively from its own defintion in C++?

I'm new to C++ and I need a class member function to call itself from its own definition, like this -
class MyClass {
public: // or private: ?
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// ...
}
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
And, will there be any difference if myfunction() belongs to public: or private:?
Since the function isn't static, you already do have an instance to operate on
void MyClass::myfunction()
{
// Some code here
// ...
this->myfunction();
// ...
}
You could leave the this-> off, I was just being more clear about how the function is able to be called.
myfunction() is in the scope of the class, so you can "simply" call it:
class MyClass {
public:
// Some code here
// ...
void myfunction();
// ...
};
void MyClass::myfunction()
{
myfunction();
}
Note, however, that this will give a stack overflow. You need a means to stop the recursion.
Member functions are actually a form of syntactic sugar. They describe a function that somehow secretly takes a pointer to an object instance which, inside the function, is accessible as this.
struct Foo {
vod bar();
};
Foo foo;
foo.bar();
What you're really doing in the call here is calling a Foo::bar(&foo); and bar is really taking a pointer Foo* this. How that's done varies from implementation to implementation, some compilers/architectures will use a special register to track the current object.
An additional piece of syntactic sugar makes all member variables and functions visible to you within a member function as though they are locally scoped
struct Foo {
int i;
int add(int n) {
return i + n;
}
int addx2(int n) {
return add(n) * 2;
}
};
What's actually happening here is:
return this->i + n;
and
return this->add(n) * 2;
This means its very easy to run into situations where you have conflicts between local and member names.
struct Foo {
int i;
Foo(int i) {
i = i; // not what you expected
}
};
For this reason, many engineers make careful use of case or prefixes or suffixes to help them distinguish members, parameters and variables.
struct Foo { // Uppercase for types and functions
int m_i; // m_ for member
Foo(int i_, int j_) {
int i = sqrt(i));
m_i = i + j_;
}
int Add(int i) {
return i_ + i;
}
};
There are various different patterns people use - some people use _name to denote a member, some use name_ and fn_ to denote members.
struct Foo {
int i_;
int add_(int _i) {
return i_ + _i;
}
};
The main thing is to be consistent.
but I don't know the proper syntax for it and how can it be called by itself without creating an object usually done like this - object_name.member_function(), if possible?
Use:
void MyClass::myfunction()
{
// Some code here
// ...
// Call MyClass::myfunction() here, but how?
// One way to call the function again.
this->myfunction();
// ...
}
this->mufunction() can be replaced by myfunction(). Use of this is a stylistic option that makes the code easier to read for some, like me.
And, will there be any difference if myfunction() belongs to public: or private:?
No, there won't be. You can call any member function of the class from another member function.

C++ ...when all the arguments have default values

I guess that this is a very absurd/basic question, but still:
class m
{
public:
void f(int ***);
/***/
}
void m::f(int ***a = NULL)
{
/***/
}
The call to f (as well as any function which has default values for all the arguments) doesn't accept 0 arguments. Why? How should I format the declaration then?
That works fine if the function definition is in the header file. The rule is that whoever is calling the function has to 'see' the default value.
So, I'm guessing you have the function definition in a separate source file. Assuming that's the case, just put the default in the function declaration (in the class):
class m
{
public:
void f(int *** = 0);
/***/
};
You'll also need to remove the default value from the function definition as you can only define the default in a single place (even if the value itself is the same).
This will work:
class m
{
public:
void f(int ***a = NULL);
};
void m::f(int ***a)
{
}
Default values in C++ are syntactic sugar; the compiler essentially inserts the argument for you at the callsite. This means that the compiler needs to know what the default value is, so it must be supplied by the function declaration.
This also means that if you have inheritance and virtual methods, the default values used are the ones from the static type (i.e., what type the compiler thinks the object is), not from the runtime type. For example:
class Base
{
public:
virtual ~Base() { }
virtual std::string foo(std::string s = "b") { return "Base:" + s; }
};
class Derived
: public Base
{
public:
virtual std::string foo(std::string s = "d") { return "Derived:" + s; }
};
int main(void)
{
Derived d;
Base& b = d;
std::cout << b.foo() << std::endl;
return 0;
}
will print Derived:b, not Derived:d.