为什么这个'这个'指针在构造函数初始化列表中使用?

时间:2015-04-27 01:00:24

标签: c++

我的意思是,我们无法做到:

class A {
    int i;
    char c;
public:
    A(int i = 0, char c = ' ') : this->i(i), this->c(c) {}
};

是因为实例尚未创建或类似的东西?

4 个答案:

答案 0 :(得分:2)

初始化程序列表中不需要this关键字,因为必须在类中声明初始化程序列表中的任何内容。当你这样做

class MyClass
{
    int member;
public:
    MyClass(int member) : member(member) { }
                          ^^^^^ Can only be resolved to a member of MyClass
}
初始化列表中的

member不允许引用类中int member以外的任何内容。因此,如果编译器必须在初始化列表中同时支持member(member)this->member(member),则此关键字是不必要的,并且会增加额外的解析难度。虽然给人的印象是可以同时初始化初始化列表中的非成员变量。

答案 1 :(得分:1)

如果您查看overview of the C++ grammar,特别是mem-initializer-list部分,您会看到初始化列表应包含identifier(expression)classname(expression)个条目。 identifier被定义为here为数字和非数字的字符串(a-z,A-Z,_)。

您的this->identifier(expression)与此不匹配,因此不允许这样做。无论如何,这没有必要,因为这里没有歧义。 identifier始终是类的成员变量,因此很清楚引用了i

class A {
    int i;
    char c;
public:
    A(int i = 0, char c = ' ') : i(i), c(c) {}
};

答案 2 :(得分:0)

您不需要像这样使用this

class A {
    int i;
    char c;
public:
    A(int i = 0, char c = ' ') : i(i), c(c) {} // syntax makes this good
};

这完全没问题,并且完全按照您希望的方式运作。

语法规则意味着参数不能作为初始化的变量出现,只能作为参数出现。因此,编译器必须从参数解析parens i()之外的变量作为类成员和parens (i)中的变量,因为他们隐藏由于范围规则导致的成员变量。

A(int i = 0): i(i) {}
              ^       - syntax says that i must be a member 

A(int i = 0): i(i) {}
                ^     - syntax says normal scoping rules apply

在parens之外,必须必须成为类成员,但中的范围内,范围规则就像在构造函数体中一样 - 参数隐藏成员变量。

因此,将参数命名为与数据成员相同的是一种非常安全的模式。

答案 3 :(得分:0)

这是因为this指针需要位于以下之一:

cppreference

  

它可能出现在以下情况中:
  1)在任何非静态成员函数体内,包括成员   初始化列表
  2)在非静态成员的声明中   在(可选)cv-qualifier序列之后的任何地方运行,   包括动态异常规范(不建议使用),noexcept   规范(C ++ 11)和尾随返回类型(自C ++ 11起)
  3)   在非静态数据成员的大括号或相等的初始化程序中(因为   C ++ 11)

class Foo {
    int a[sizeof(*this)]; // error, not inside a member function
};

类似地:

class A {
    int i = sizeof(*this); // valid - brace-or-equal initializer
    char c;
public:
    // Error, not inside member function.
    A(int i = 0, char c = ' ') : this->i(i), this->c(c) // invalid
    {}
};

当放在构造函数体内部时,它将起作用:

A(int i = 0, char c = ' ')
{
    this->c = c; // 'this->' required for disambiguation
    this->i = i;
}

A(int i = 0, char c = ' ') : i(sizeof(*this)) // also valid
{}

通常没有必要明确使用this->