在Type :: var?

时间:2017-05-31 08:53:34

标签: c++ c++11 scope operators member

考虑以下示例:

class A { int x; };

现在什么是A::x

  • 它不能是左值,因为它不引用存储位置。
  • 它不能是类型,因为类型为decltype(A::x)

5 个答案:

答案 0 :(得分:11)

事实上,这是一个左值。 [expr.prim.id.qual]/2

  

一个嵌套名称说明符,表示一个类后面跟着的[...]   该类([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;
    }
}

如果您在课程xprotected 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;
}