• Forum
  • Lounge
  • People that put "this->" before members:

 
People that put "this->" before members:

Pages: 12
Why?
closed account (3hM2Nwbp)
As opposed to? bool m_boolean?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class X
{
  // imagine that 'arg' is a very good description of what the member is
  private: int arg;

  public:
    // I would very much hope that such a good description is exposed in the public API
    // and not something like arg_renamed_to_avoid_scoping_issue
    void setArg(int arg)
    {
      arg = arg; // oops.
      this->arg = arg; // that's better.
    }
};


It works well when auto-generating code.

Maybe if the ISO committee would push a certain convention we could avoid things like this all together.
Last edited on
closed account (z05DSL3A)
Why not?
Am I wrong, or can you use this.member? And I don't see the issue here. Using this is much cleaner than making up another name for the same data.
@ResidentBiscuit
No. Unfortunately someone decided that in C++, this would be a pointer instead of a reference so it has to be this->member or (*this).member. In C# and Java you can use this.member because this is a reference.

[edit]
I suppose you could do this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Class {
private:
    Class& self;
public:
    Class() : self(*this)
    {
        self.print_hello();
    }

    void print_hello()
    {
        std::cout << "Hello!" << std::endl;
    }
};

[/edit]

@Disch
It makes it obvious both to human readers and the compiler that you're referring to an instance member rather than a temporary variable, external function or static member. I don't do it unnecessarily in C++ because I find this-> unattractive, but in C# or Java I always put this. before an instance member.
Last edited on
In past I used to find this->member nice and attractive. Now I don't anymore, I don't know how it happened.
The only thing I can think of is that, if there's no convention for prefixing member variables, it assists the reader in understanding the code. But if you prefix with 'm' or some variant, it's pointless.
Last edited on
Wow, In past I didn't know (*this) reference... :(
Great! Now gererally my code is smarter and looks much better than the old one... Thanks chrisname! :D
Just so people know - Imadatobanisa is the reincarnated Jackson Marie.
chrisname wrote:
It makes it obvious both to human readers and the compiler that you're referring to an instance or static member rather than a temporary variable, or external function or static member.


Fixed!
Practically adding “this->” prefix will increase the tokenizing and token recognition steps of unit translation during compilation of the code, and will decrease the variable namespace resolution time during code generation phase. So effetely there is no difference.

Moreover “this” pointer is not a member of class, for example
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#define me this;
class MyClass
{
public:
    MyClass * parent;

    MyClass * getGrandParent1()
    {
        // parent is a member;
        return me->parent->parent->parent; // Ok
    }

    MyClass * getGrandParent2()
    {
        // this is a not a member;
        return this->this->this; // Error!
    }

    friend void friendFunction();
};

void friendFunction()
{
    MyClass *c;

    std::cout << c->parent; //Ok

    std::cout << c->this;   // Error.
} 


Also ever wondered
1. What is access level for “this” (public/private/protected). I know someone will say private, in that case why can’t we access “this” (Private member) from a friend function
2. I think “this” was originally provided to get the address of the class in-side the class methods, to perform some low level byte manipulation possible, later found other uses like name collision avoidance, etc.
3. I think “this” is subjective word. When some says this, it kind of implies that he is not part of “this”. Hmm I guess “me”/“our” is more appropriate.


Edit: I ment address of object (isn't it obvious)
Last edited on
1. You just said it wasn't a member, so how would it have an access level? It is a "hidden" parameter to class methods.

2. this is passed to the function so that the function knows what object it is operating on. Every use of a data member inside a class function uses this implicitly (if it isn't done explicitly.) There isn't any such thing as an address of a class.
chrisname wrote:
I don't do it unnecessarily in C++ because I find this-> unattractive, but in C# or Java I always put this. before an instance member.
why is . better than ->? By the way in C#/Java nearly every non trivial data type is a pointer.It's just veiled. This allows to omit the #include because the size of the types are known

Santosh Reddy wrote:
Moreover “this” pointer is not a member of class
You are right. this is hiddenly passed as the first parameter to a member function.
Practically adding “this->” prefix will increase the tokenizing and token recognition steps of unit translation during compilation of the code, and will decrease the variable namespace resolution time during code generation phase.
Pfft. Not like it would make much of a difference anyway. Most of the compilation time is spent on templates, not lexing or resolving names.

“this” pointer is not a member of class
return this->this->this; // Error!
Well, duh.

1. What is access level for “this” (public/private/protected).
This is a property of members, and you just said that this is not a member, therefore this question makes as much sense as asking about the circumference of a square.

2. I think “this” was originally provided to get the address of the class in-side the class methods, to perform some low level byte manipulation possible, later found other uses like name collision avoidance, etc.
Much more important is the ability to pass the object (classes don't have addresses) to other functions.
this->member is typically used in template code to specify that member is a dependent name.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <vector>

template < typename T > struct my_vector : std::vector<T>
{
    // ...
    bool my_empty() const
    {
        // return empty() ; // *** error 'empty' is a a nondependent name
        return this->empty() ; // fine, 'empty' is a dependent name
        return std::vector<T>::empty() ; // also fine, 'empty' is a dependent name
    }
};

template struct my_vector<int> ;


It is also used in code emitted by many code generators; they don't want to worry about whether the name of a member has been hidden by the surrounding code.

And it is used in newbie code which is all written inside an IDE; this-> triggers autocompletion.
Last edited on
Just pointing out, thiscall implies the this pointer is in the ecx register on 32-bits. So it's not really a common parameter like for stdcall/cdecl/fastcall.
@EssGeEich

Am I able to call a __thiscall function by assembly? Is ecx a structure parameter which the function will use as a glocal variable?
Last edited on
"Ecx" is a register which is like a very very fast CPU variable. A call to a member function looks like:

1
2
3
mov ecx, (Pointer to the class)
push (Parameters)
call (Function)


Wikipedia wrote:
thiscall
This calling convention is used for calling C++ non-static member functions. There are two primary versions of thiscall used depending on the compiler and whether or not the function uses variable arguments.

For the GCC compiler, thiscall is almost identical to cdecl: the calling function cleans the stack, and the parameters are passed in right-to-left order. The difference is the addition of the this pointer, which is pushed onto the stack last, as if it were the first parameter in the function prototype.

On the Microsoft Visual C++ compiler, the this pointer is passed in ECX and it is the callee that cleans the stack, mirroring the stdcall convention used in C for this compiler and in Windows API functions. When functions use a variable number of arguments, it is the caller that cleans the stack (cf. cdecl).
Last edited on
@cire
You can use this-> to refer to static members? That seems illogical.

coder777 wrote:
why is . better than ->?

It's not, necessarily; I just think it looks better. I guess you could argue that . doesn't require a pointer dereference which might save you a few CPU cycles. Then again, I'm not sure how references are implemented, so it might not save any time at all, or even take more time.
chrisname wrote:
You can use this-> to refer to static members? That seems illogical.
Unlike common sense, in C++ and Java you can always access static members from non-static contexts. It's my most hated feature of both languages and I wish it could go away, but it would break a lot of working code that was written by people who didn't know what they were doing.

As for prefixing with this-> I don't do it myself because I never have a parameter named impl. Well, I guess impl-> is the same length as this->
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//MyLibrary.hpp
struct MyLibraryClass
{
    void *Tag; //for client use

    MyLibraryClass();
    ~MyLibraryClass();

    void PublicInterface(int x);
    int PublicInterface();
private:
    struct Impl;
    Impl *impl;

    MyLibraryClass(MyLibraryClass const&) = delete;
    MyLibraryClass &operator=(MyLibraryClass const&) = delete;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//MyLibrary.cpp
struct MyLibraryClass::Impl
{
    int x;
};
MyLibraryClass::MyLibraryClass() : Tag(nullptr), impl(nullptr)
{
    impl = new Impl(/**/);
}
MyLibraryClass::~MyLibraryClass()
{
    delete impl, impl = nullptr;
}
void MyLibraryClass::PublicInterface(int x)
{
    impl->x = x;
}
int MyLibraryClass::PublicInterface()
{
    return impl->x;
}
Why use such an absurd design pattern? To hide implementation details and reduce coupling as well as avoid the overhead of virtual method calls with interfaces for simple classes. It is definitely more work but it resolves many issues with tight coupling between public interface and internal implementation. I don't know who invented it, I learned it from someone else.
Last edited on
Pages: 12