struct Tuna{
int x = 50;
Tuna() : x(200){
}
Tuna &foo(){
return *this; //return type is reference to Tuna class
}
/****************
Returns a new object made by copying the current object
*****************/
Tuna bar(){
return *this;
}
void set(int value) { x = value; }
};
int main(){
// a pointer to class
Tuna tt;
Tuna *foobar = &tt;
foobar->set(20);
cout << foobar->x << endl;
Tuna t;
t.foo().set(1);
cout << t.x << endl;
system("pause");
return 0;
}
They are just the same. What are the advantage of using one over the other?
Or is it just a programmer's preferencce?
EDIT: sorry about that. i submit it early. I edited my code.
What i mean by the same is that you can call function from Tuna class with either using the return *this pointer or creating a pointer to class. So whats the difference?
Can you give me a reason why would i return a this pointer?
If I understand you...
return *this; is not returning a this pointer. this itself is a ponter, so *this is dereferencing the pointer to get the object. Depenting on the return type of the function you then either return a reference to the object or a temporary copy of the object.
this is a pointer that is implicitly created for each member function.
When you have:
1 2 3 4 5 6 7 8 9 10 11 12 13
struct Foo {
int x = 42;
void foo( int a ) {
x += a;
// you could be more explicit and write here:
// this->x += a;
}
};
int main() {
Foo bar;
bar.foo( 7 );
}
One could write equivalent (pseudo)code:
1 2 3 4 5 6 7 8 9 10 11 12
struct Foo {
int x = 42;
};
void foo( Foo * this, int a ) {
this->x += a;
}
int main() {
Foo bar;
foo( &bar, 7 );
}
You don't have to return a reference to the object but it can be beneficial.
Lets say you have your Tuna object t and you want to call foo() and then bar() on it.
if foo and bar return void you would have to write:
1 2
t.foo();
t.bar();
if you return a reference to the object you can then chain the calls:
t.foo().bar();
You have already made use of chaining (without realising it) in code such as cout << t.x << endl;. Syntactic sugar hides the fact that << is a function.
These two lines of code are the same:
1 2
std::cout << x << " " << y << std::endl;
std::cout.operator<<(x).operator<<(" ").operator<<(y).operator<<(std::endl);
_____________________________________
Edit:
another way to think about it is with substitution. In t.foo().bar();, you can substitute the call f.foo() with its returned object. If foo() returned void you would then efectivly have (void).bar();. When you return a reference to the object that contains the function you would have t.foo() replaced with t so you would still have t.bar(); which is valid.