简体   繁体   English

在参数化构造函数中使用 this 指针

[英]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.如果您在示例中编写name = name ,则将局部变量name分配给自身。

By using this you explicitely refer to your object and thus explicitely state that you want to assign the name member.通过使用this ,您明确地引用了您的 object,因此明确地引用了您想要分配name成员的 state。

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).但是考虑一下当您(假设地)想要使用成员name初始化成员id (忽略参数)时会发生什么。 In that case this->name becomes neccessary again.在这种情况下, this->name再次成为必需品。

This whole issue can be circumvented by naming the members or arguments differently, eg m_ is a common convention: m_name = name可以通过以不同方式命名成员或 arguments 来规避整个问题,例如m_是一个通用约定: m_name = name

In the first one, your parameters of the constructor shadow the fields of the class.在第一个中,构造函数的参数会影响 class 的字段。 You need this-> to specify, which variable to assign the value to.您需要this->来指定将值分配给哪个变量。 In the second you use a initialization list.在第二个中,您使用初始化列表。 (Read here for more information: https://isocpp.org/wiki/faq/ctors#init-lists ) (阅读此处了解更多信息: 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.对于第一种情况,在构造函数主体中,非限定名称总是在构造函数 scope 中找到,并引用构造函数参数。 Then name lookup stops, the further scope including class scope won't be examined.然后 名称查找停止,进一步的 scope 包括 class scope 将不会被检查。 Then when you want to specify data members you have to qualify explicitly like this->name , otherwise, name = name;然后,当您要指定数据成员时,您必须像this->name那样明确限定,否则, name = name; means assigning name by itself .意味着自己分配name

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 ,[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. 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. [ 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.可以使用限定名称指定隐藏基 class 的 mem-initializer-id。 — 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 . — end note ]除非 mem-initializer-id 将构造函数的 class 命名为构造函数的 class 的非静态数据成员,或者该 class 的直接或虚拟基数,否则构成 mem-D61

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.这意味着,mem-initializer-id 将在 class 的 scope 中查找,它不会也不能引用构造函数参数。

On the other hand, [class.base.init]/15 ,另一方面, [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. mem-initializer 的 expression-list 或 braced-init-list 中的名称在为其指定 mem-initializer 的构造函数的 scope 中进行评估。

The names in initializer expression are looked up in the scope of the constructor, then constructor parameters are found.在构造函数的 scope 中查找初始化表达式中的名称,然后找到构造函数参数。 So name(name) means initializing the data member name by the constructor parameter name .所以name(name)表示通过构造函数参数name初始化数据成员name

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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