我一直认为<class>::<variable>
用于访问静态成员。但是,我很惊讶地发现以下编译得很好。 (我会使用内联评论中显示的this->
。)
对Google / StackOverflow的进一步调查没有显示与此行为有关的任何内容,我想知道是否有人可以对此有所了解。
class Test {
private:
int x;
public:
void set_x(int x) {
// this->x = x;
Test::x = x;
}
};
int main(int argc, char *argv[])
{
return 0;
}
ENV:clang版本7.0.0-(主干)
答案 0 :(得分:2)
::
是范围解析运算符,可用于指定引用所引用的同名但具有不同但可见范围的多个符号中的哪一个。
在此示例中可以使用范围解析或this->
,但范围解析本身在该语言中具有更广泛的适用性。
答案 1 :(得分:0)
http://eel.is/c++draft/basic.lookup.qual#class.qual
如果qualified-id的嵌套名称说明符指定了一个类,则为该名称 在查找范围内查找嵌套名称说明符后指定 class([class.member.lookup]),除了下面列出的情况。名字 应代表该类别或其基础之一的一个或多个成员 课程([class.derived])。 [注意:可以使用a来引用类成员 在其潜在范围内的任何一点都是qualified-id([basic.scope.class])。 - 结束 注意]
答案 2 :(得分:0)
是的,它只是指定声明对象的类名/命名空间。可能会有更多人为的案例,如下所示:
struct Base {
virtual int answer() const { return 42; }
};
struct Left: public virtual Base {
virtual int answer() const { return 314; } // raise the heat
};
struct Right: public virtual Base {
virtual int answer() const { return -42; } // to the other side
};
struct Bottom: Left, Right {
virtual int answer() const { return Base::answer(); } // back to basics
};
#include <iostream>
int main() {
Bottom b;
std::cout << b.answer() << std::endl; // 42
std::cout << b.Right::answer() << std::endl; // -42
std::cout << b.Left::answer() << std::endl; // 314
std::cout << b.Base::answer() << std::endl; // again, 42
}
使用静态成员的东西,你不能以其他方式访问它们(并且它们不能是虚拟的,顺便说一句。)(仍然,如果类Child
派生Base
并且都定义了静态成员{{1你应该使用合格的表格 - staticMember
或Base::staticMember
- 来消除两者之间的歧义;在这种情况下,非限定版本会引用Child::staticMember
。)
但是非静态方法在其中有一个对象上下文,因此成员可以使用不合格 - 仍然可以 以其他方式使用。
P.S。 Child
来自哪里?我有时会在这里和那里看到它,但仍然没有人能够解释原因。
答案 3 :(得分:0)
使用类名称限定实例变量(或成员函数)有几个原因。此列表并非详尽无遗,仅提及我们将在对象实例上使用它的情况,而不是类型:
在成员函数中,如果derived和parent具有相同的成员名称,则派生名称会隐藏基数。资格认证可以允许访问基地。这适用于变量和成员函数。
如果在具有多重继承的层次结构中的成员函数内,则可以选择要使用的父级。
它可以通过调用指定类型的函数实现来绕过虚函数调度机制,而不是在最重写的类型中。示例:d.Base::foo();
它可用于指定由局部变量隐藏的成员,类似于使用this-&gt;限定成员; (虽然我从来没有见过这样做,而是更喜欢这个 - >相反。)
它经常与“using”声明一起使用,将基类函数名称引入派生类的重载集,该派生类添加了一些具有相同名称的类。如果没有这个,基本名称将被隐藏。