定义类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++
引用哪一个?
答案 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
}