Peter
Peter

Reputation: 361

Accessing members from an object itself with either THIS or member scope

What is the proper way of accessing a member data/function that is part of the method's class? There appears to be 3 means:

class test{
    private:
        int variable;
    public:
        void setVariable(int value) {
            variable = value;        // method 1, using the variable name directly
            this->variable = value;  // method 2, via pointer dereference of 'this'
            test::variable = value;  // method 3, via scope operator
        }
};

They all seems to work as far as I can tell. Are they equivalent? Is there a reason to use one over the other beside style/consistency?

Upvotes: 3

Views: 125

Answers (8)

andre
andre

Reputation: 7249

  • Method 1: This is the common way it is done.
  • Method 2: This is the best and most consistence way to do it. It makes it very clear to read and understand what's happening.
  • Method 3: I've never seen done in real world code.

As a side note: When using method 1 if there is a naming conflict with the function parameter and member variable the function parameter will be used over the member variable.

if we have:

void setVariable(int variable) {
    variable = variable;        // method 1, this does not change the member variable.
    this->variable = variable;  // method 2, via pointer dereference of 'this'
    test::variable = variable;  // method 3, via scope operator
}

Upvotes: 1

Zane
Zane

Reputation: 926

And to add to the above answers: Some code styles like to identify member variables using a fixed prefix like _ or m. Using "method 2" is another (and imho much nicer way) of achieving this clarity in the code.

Prefering this->value over value is also a little like using std::cin instead cin with a using namespace std.

Upvotes: 0

In general it does not matter so the simpler options member = value; is preferred. In some cases there might be ambiguity with a local variable and there you can qualify with the this-> prefix, but a better approach would be avoid the ambiguity altogether.

There are however some corner cases where it does matter. When dealing with virtual functions, using a qualified name (type::member) disables runtime dispatch and ensures that the final overrider at the type level is called:

struct base {
   virtual int f() { return 1; }
};
struct derived : base {
   virtual int f() { return 2; }
   void g() {
      std::cout << f() << "\n";
      std::cout << derived::f() << "\n";
   }
};
struct mostderived : derived {
   virtual int f() { return 3; }
};
int main() {
   mostderived d;
   d.g();            // 3 2
}

When dealing with template classes and inheritance, lookup is performed in two phases. During the first phase, non-dependent names have to be resolved. An unqualified name is a non-dependent name, so in some cases you need to qualify with either this-> or type::, and the distinction above still applies. The extra qualification serves to make the name dependent:

template <typename T>
struct derived : T {
   void g() {
      // std::cout << f() << "\n";    // Error, cannot resolve f() [*]
      this->f();                      // Ok, pick final overrider at runtime 
      derived::f();                   // Ok, pick overrider here: base::f()
   }
};
struct base {
   virtual int f() { return 1; }
};
struct mostderived : derived<base> {
   virtual int f() { return 3; }
};
int main() {
   mostderived d;
   d.g();                             // 3, 1
}

Upvotes: 3

fernacolo
fernacolo

Reputation: 7439

There is no difference in performance. The :: is used to avoid ambiguities, such as when you have a local variable with same name of a field, or a base class that declares a field with same name of a field in a derived class. The -> is supported because the type of this is a pointer to object, so the compiler must accept this->something, and that can also be used to avoid ambiguities or just to let code more clear.

Upvotes: 0

Jerry Coffin
Jerry Coffin

Reputation: 490148

For code inside the object, it generally makes no difference, so it's usually cleanest to just use variable = value; and be done with it.

Sometimes in a template, you can run into a situation where just using the variable name by itself is ambiguous, and this->variable removes that ambiguity -- but this is rare enough that I definitely would not use this->everything on a regular basis just because it might be useful once in a great while.

Upvotes: 1

Syntactic Fructose
Syntactic Fructose

Reputation: 20074

The pointer this is often used for comparison in an overloaded operator of a class. One of its uses can be if the parameter passed in the function is the same as the object itself, for example:

class CDummy {
  public:
    int isitme (CDummy& param);
};

int CDummy::isitme (CDummy& param)
{
  if (&param == this) return true;
  else return false;
} 

This is also used to return a pointer to the object itself

ClassEx ClassEx::Func(//params)
{
    //code
    return *this;
}

As for normal comparison, value instead of this->value will be more efficient to use, the use of this-> is ambiguous unless you're checking values.

Upvotes: 0

Magnus Hoff
Magnus Hoff

Reputation: 22089

In addition to style and consistency, as you mention, sometimes you have to use a specific syntax to disambiguate.

"method 2" can be used to disambiguate between local variables and class members.

"method 3" can be used to disambiguate between fields with the same name in different places of your class hierarchy.

Upvotes: 3

Ed Heal
Ed Heal

Reputation: 60007

Use method 1

variable = value;

Saves you buying a new keyboard so frequently!

(Having said that I should stop stilling coffee over mine!)

Upvotes: -1

Related Questions