类成员是否需要在类定义中以`class ::`作为前缀?

时间:2013-05-10 13:08:17

标签: c++ class namespaces

定义类cls时,在cls::自己的定义中使用类名cls时,是否有必要(或良好做法)为成员添加前缀,或者是隐含地完成了? E.g。

class cls {
    int x;
    void foo();
    void bar();
}
void cls::foo() {
    x++;    // or use cls::x?
    bar();  // or cls::bar()?
}

如果是这样,那么创建一个类cls会自动意味着它也是一个命名空间(因为我认为::运算符只用于命名空间)?

编辑(跟进): 如果我们不使用cls::this->,那么如果我的来源在类外还有一个变量x怎么办? cls::foo()将如何知道x++引用哪一个?

3 个答案:

答案 0 :(得分:2)

使用类名显式限定成员变量使用是个坏主意。充其量,它是不必要的(或者必要时,这个 - >成员更好)并禁止重构(如果重命名该类,更多的地方要改变),最坏的情况是它会引入错误,因为对虚拟函数的合格调用不会调度为重写版本

答案 1 :(得分:1)

NOP。至少没有。

您可以使用this->让读者更清楚。但是::是另一回事。它用于访问静态成员变量或函数。

int x;                  // Global x
namespace ot { int x; } // another x
class cls {
    int x;              // Normal member
    static int y;       // Static member
    void foo();
    static void bar();  // Static member function
}
void cls::foo() {
    this->x++;    // Modify own x. 
    x++           // Modify own x. This has implicit this->
    ::x++;        // Modify the global x.
    ot::x++;      // Modify the x in namespace ot.
    cls::y++;     // modify the static member
    cls::bar();   // static member function. same as bar()
}

答案 2 :(得分:1)

上面显示的代码定义一个类,但最初只有声明成员函数(然后定义它们)。我只提到这一点,因为术语对于有效沟通很重要。

如果您将类成员内联定义,则不要使用范围解析运算符 ::,例如:

class cls {
    void hello() { cout << "Hello world"; }
};

如果你单独定义它们,那么你需要它,因为否则编译器无法知道你打算定义什么函数:

class cls {
    void hello();
};

void cls::hello() { cout << "Hello world"; };

通常,范围解析运算符的使用不限于使用命名空间;只要需要向编译器提供完全限定名称,就可以使用它。

在大多数情况下,从类范围内访问类成员时,可以使用不合格的名称;编译器将自行解决它们。例如,在您的代码中,所有这些都是等效的:

x++;
cls::x++;
this->x++;
this->cls::x++; // yes, this too

只要有多个具有相同名称的成员,您就需要对名称进行限定,并且编译器会将非限定名称解析为您想要的成员之外的其他名称。例子:

void cls::foo(int x) {
    x++;       // increments the argument
    cls::x++;  // increments the member
    this->x++; // also increments the member
}

还要考虑cls可能来自base,而base也可能定义x。在这种情况下,它的工作原理如下:

void cls::foo() {
    x++;       // increments foo::x
    cls::x++;  // increments foo::x
    base::x++; // increments base::x
}