3

It's a fact that you can explicitly access member variables (inside a member function, and not particularly a constructor) using this syntax : this->member_name (i.e. to distinguish with a function argument with the same name).

Besides this, I thought that the syntax ClassName::static_member was reserved to access static members outside of a class.

Then I was surprised when I realized that the following set_2() method was working as one could expect:

#include <iostream>

struct A {
    int x;
    // The two following methods seem to act similarly:
    void set_1(int x) { this->x = x; }
    void set_2(int x) { A::x = x; }
};

int main ()
{
    A a;

    a.set_1(13);
    std::cout << a.x << std::endl;

    a.set_2(17);
    std::cout << a.x << std::endl;

    return 0;
}

Output:

13
17

Is is a good and valid practice to use the scope operator (A::x) in this case? I would personnally prefer it, instead of using the this->x syntax.

3
  • 3
    IMHO, don't use names that causes conflicts like that and you don't have to use either syntax. Commented Jan 5, 2016 at 15:12
  • 1
    @JoachimPileborg : many people give this advice, but I find it quite more clear for my part to give the same name, especially with a direct assignment (only one name for one task) Commented Jan 5, 2016 at 15:17
  • 1
    I would decorate one of the names. I quite like trailing _ as a member variable decorator. Alternatively, you can use prefix "m_" for the member and/or "a_" for the argument. The important thing is to pick one style and stick to it. Commented Jan 5, 2016 at 15:19

3 Answers 3

6

Using A::x in this case is valid, but I think this->x is more idiomatic and less error-prone (the reader of the code can immediately see that x is a member of the class, without thinking what A is).

Sign up to request clarification or add additional context in comments.

Comments

3

According to the C++ Standard (3.3.7 Class scope)

2 The name of a class member shall only be used as follows:

— in the scope of its class (as described above) or a class derived (Clause 10) from its class,

— after the . operator applied to an expression of the type of its class (5.2.5) or a class derived from its class,

— after the -> operator applied to a pointer to an object of its class (5.2.5) or a class derived from its class,

— after the :: scope resolution operator (5.1) applied to the name of its class or a class derived from its class.

For example data members of methods of a derived class can hide data members and/or methods of its base class. To access data members and nethods of the base class you can use the scope resolution operator.

struct Base
{
    virtual ~Base() {};
    virtual void Hello() const { std::cout << "Base" << std::endl; }
};


struct Derived : Base
{
    virtual void Hello() const 
    { 
        Base::Hello();
        std::cout << "and Derived" << std::endl; 
    }
};

Derived d;

d.Hello();

Comments

2

The A::x, in your case, still refers to your regular member variable; it just explicitly specifies which x you mean. Consider a class that derives from two other classes which have a member of the same name (not that that's very good coding style):

struct A { int x; };
struct B { int x; };
struct C : A, B
{
  int foo() const
  {
    // return x;  // ambiguous: which x do you mean?
    return A::x;  // unambiguous
  }
};

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.