简体   繁体   中英

Using this pointer in parameterized constructor

when i passed the parameters to constructor and do the assignment inside body, i have to use this pointer otherwise it won't run.

class Employee
{
    public:
        string name;
        const char *id;
        int age;
        long salary;


        Employee (string name,const char* id, int age, long salary)   
        {
            this->name = name;
            this->id = id;
            this->age = age;
            this->salary = salary;
        };
};

But if I use other method then there is no need of this pointer. why is it so?

Employee(string name,const char id[], int age, long salary): name(name),id(id),age(age),salary(salary)
         {};

Because the names clash. If you write name = name in your example, you are assigning the local variable name to itself.

By using this you explicitely refer to your object and thus explicitely state that you want to assign the name member.

The initializer list works because only members can appear in it. But think about what happens when you (hypothetically) want to initialize the member id with the member name (disregarding the argument). In that case this->name becomes neccessary again.

This whole issue can be circumvented by naming the members or arguments differently, eg m_ is a common convention: m_name = name

In the first one, your parameters of the constructor shadow the fields of the class. You need this-> to specify, which variable to assign the value to. In the second you use a initialization list. (Read here for more information: https://isocpp.org/wiki/faq/ctors#init-lists )

For the 1st case, in the constructor body, the unqualified names are always found in the constructor scope and refer to the constructor parameters. Then name lookup stops, the further scope including class scope won't be examined. Then when you want to specify data members you have to qualify explicitly like this->name , otherwise, name = name; means assigning name by itself .

For the 2nd case, data members are initialized (btw this is not assignment as the 1st case) by member initializer list. From [class.base.init]/2 ,

(emphasis mine)

In a mem-initializer-id an initial unqualified identifier is looked up in the scope of the constructor's class and, if not found in that scope, it is looked up in the scope containing the constructor's definition. [ Note: If the constructor's class contains a member with the same name as a direct or virtual base class of the class, a mem-initializer-id naming the member or base class and composed of a single identifier refers to the class member. A mem-initializer-id for the hidden base class may be specified using a qualified name. — end note ] Unless the mem-initializer-id names the constructor's class, a non-static data member of the constructor's class, or a direct or virtual base of that class, the mem-initializer is ill-formed .

That means, the mem-initializer-id will be looked up in the scope of the class, it won't and can't refer to the constructor parameter.

On the other hand, [class.base.init]/15 ,

Names in the expression-list or braced-init-list of a mem-initializer are evaluated in the scope of the constructor for which the mem-initializer is specified.

The names in initializer expression are looked up in the scope of the constructor, then constructor parameters are found. So name(name) means initializing the data member name by the constructor parameter name .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM