考虑以下示例:
class A { int x; };
现在什么是A::x
?
decltype(A::x)
。答案 0 :(得分:11)
一个嵌套名称说明符,表示一个类后面跟着的[...] 该类([class.mem])或其基类之一的成员的名称 类,是 qualified-id [...]。结果是成员。类型 结果是成员的类型。结果是左值如果 成员是静态成员函数或数据成员和prvalue 否则。
虽然它在类成员访问表达式之外的用法受到[expr.prim.id]/2的严格限制,但它可以特别用于未评估的操作数,其左值可以显示:
struct A {
int x;
};
void f(int &);
using p = decltype(&(A::x)); // p is int*; the parens prevents forming a pointer-to-member
using q = decltype(f(A::x)); // q is void
答案 1 :(得分:6)
A::x
仅仅是一种不太模糊的引用成员x
的方式,如果本地上下文阴影该成员可能是必要的:
<小时/> 例1:
子类也有成员x
。
struct B : public A
{
int x;
void foo()
{
int local_x = x;
int parent_x = A::x;
}
}
如果您在课程x
中protected
A
(目前为private
),则会编译。
<小时/> 例2:
您甚至可以在A
的成员功能中使用x
作为参数:
class A {
int x;
void foo(int x)
{
int parameter_x = x;
int member_x = A::x;
}
};
答案 2 :(得分:2)
除了Bathsheba的答案,当你在班级范围内时这是正确的,A::x
也可以用作指向成员的表达式的一部分,即&A::x
,它返回int A::*
。
在这种情况下,独立A::x
无效,因此它返回的问题没有实际意义。
答案 3 :(得分:0)
来自C ++标准(5.1主要表达式)
9表示类的嵌套名称说明符,可选地后跟 关键字模板(14.2),然后是成员的名称 该类(9.2)或其基类之一(第10条)是 合格的身份; 3.4.3.1描述了类成员的名称查找 出现在qualified-id中。结果是成员。的类型 结果是成员的类型。 如果是,结果是左值 member是静态成员函数或数据成员和prvalue 除此以外。 [注意:可以使用a来引用类成员 在潜在范围内的任何一点都是合格的(3.3.7)。 - 注意 ] ...
限定名称允许指定隐藏的名称,例如派生类和基类具有相同名称的成员。例如
#include <iostream>
struct A
{
int i;
};
struct B : A
{
B( int i ) : A { i }, i( 2 * A::i ) {}
int i;
std::ostream &out( std::ostream &os = std::cout ) const
{
return os << "A::i = " << A::i << ", B::i = " << B::i;
}
};
int main()
{
B( 10 ).out() << std::endl;
return 0;
}
程序输出
A::i = 10, B::i = 20
另外(5.1主要表达)
13一个id表达式,表示非静态数据成员或 只能使用类的非静态成员函数:
(13.1) - 作为类成员访问(5.2.5)对象的一部分 expression是指成员的class63或从中派生的类 上课,或
(13.2) - 形成指向成员(5.3.1)或
的指针(13.3) - 如果该id-expression表示非静态数据成员及其 出现在未评估的操作数中。
答案 4 :(得分:-3)
A::x
完全等同于访问JAVA中的静态变量。
关于你的例子: -
1) x 对于不同的对象是可变的
2) A :: x 将是类本身的变量。无论为每个对象声明了多少个A对象,A::x
的值在赋值之前都是相同的。
例如: -
#include<iostream>
using namespace std;
class A {
public:
static int x;
};
int A::x;
int main()
{
A a,b;
a.x=8;
b.x=6;
A::x=10;
return 0;
}