-1

How is it possible to access a class variable to assign its value when both the class variable and a parameter have the same name, without using the this pointer? I have used class_name::variable_name inside a constructor instead of the this pointer to the object. See the code below for a better understanding.

#include<iostream>
using namespace std;
class abc
{
    int x;
    public:
        abc(int x)
        {
            abc::x=x;
        }
        void prnt()
        {
            cout<<x;
        }
};
int main(void)
{
    abc A(2);
    A.prnt();
    return 0;
}

How is this possible without using the this pointer?

JaMiT
  • 14,422
  • 4
  • 15
  • 31
SDK
  • 29
  • 2
  • 5
  • What is your question? Are you asking why `abc::x=x;` works? – HolyBlackCat Oct 19 '19 at 16:03
  • 2
    I avoid the name collision altogether by using a different name for the parameter. In this case, I'd use either `xx` or `x_` for the parameter. – Eljay Oct 19 '19 at 16:08
  • You presented two questions. The first (how to ... without using `this`) is answered within your question. The second is not clear, since one answer is "it's possible because the C++ standard allows it". Perhaps you could better explain what you find confusing? – JaMiT Oct 19 '19 at 16:56

4 Answers4

1

Rename that parameter or member and/or use the initialization list (you should do that in any case).

abc(int x) : x(x) { }

Personally I would name the member variable m_x and then do

abc(int x) : m_x(x) { }
Jesper Juhl
  • 30,449
  • 3
  • 47
  • 70
1

First: I would avoid to use the same name, even if t is possible.

Second: You should initialize the variables of your class and not overwrite them later inside the constructor body! This can, if not optimized away, lead to unwanted call of default constructor of member vars.

Most people use coding conventions to function parameters and member vars, maybe something like that:

class abc
{
    int x;

    public:
        abc(int x_): x{ x_ } // use initializer list and not constructor body!
    {
    }
};

In initializer list you can use the same name for constructor parm and member var. But as said, I personally dislike it!

As a hint from the comments: You should avoid reserved identifiers as described in this answer: What are the rules about using an underscore in a C++ identifier?

Klaus
  • 24,205
  • 7
  • 58
  • 113
  • 1
    Note that prefixing identifiers with a single underscore is potentially dangerous. If that identifier started with a capital letter (maybe it's an acronym or something), then you'd be using a reserved identifier, which is undefined behavior. It's best to prefer trailing underscores rather than leading. – Nicol Bolas Oct 19 '19 at 16:55
1

Point 1: You don't really have two xs. The parameter is x. The member x's full name is abc::x.

Point 2: The compiler is smart.

When he's the only John around, you can call John Smith John and those around you can usually figure out who you're referring to. In a room full of Johns, you might need to use his full name. In the event of multiple John Smiths, you may need to go a step further and use John Paul Smith.

In a large room you could get away with calling John Paul Smith John if the other Johns are further away. Everyone nearby will assume you are referring to the the closest John. If they are wrong, you, the communicator, would have to be more explicit.

The compiler's doing the same thing. The default behaviour is to use the closest x, the one with the narrowest visible scope. That would be parameter x. If you want to use an x that is further away, you use an unambiguous name.

Notes:

While this case is easily avoidable and an easy source of bugs, making it a poor decision, you'll find you need to more fully qualify identifiers from time to time, for example when you want to call a member function of a base class from a derived class after the derived class has overridden the function.

Related, this is one of the reasons using namespace std; is usually a bad idea.

user4581301
  • 33,082
  • 7
  • 33
  • 54
0

Actually, your code compiles, runs and works in MSVC (though I wasn't sure it would). But, other than the (better) suggestion made in the comments, you could also use an initializer list:

abc(int x) : x { x }
{
}

But I would still call this 'bad' coding style.

Adrian Mole
  • 49,934
  • 160
  • 51
  • 83