静态成员是否继承?

时间:2013-05-08 17:07:26

标签: c++

我在A类中有一个静态成员变量,而B类从A类派生。

class A
{
  public:
    A()
    {
      a = 3;
    }
    static int a;
};

int A::a = 0;

class B : public A
{
  public:
    B()
    {
      a = 4;        
    }
};

void main()
{
  A objA;
  cout << "Before:" << A::a;
  B obj;
  cout << endl << "After:" << A::a;
}

根据Are static fields inherited?制作派生类型对象时,它还会创建基本类型。 我有以下问题:

  1. 如何而不是A::a我还可以访问objA.a?不应通过该类的对象访问静态变量。

  2. 如果派生类也是一个新的静态变量(特定于class B)那么为什么没有必要初始化class B的静态变量?

  3. 为什么以下输出显示为:

  4.   

    在:3

         

    之后:4

    预计在之前和之后显示3?

5 个答案:

答案 0 :(得分:3)

对静态变量的访问是继承的。请注意,无法访问具有私有访问权限的静态成员,因为这是protected关键字的用途。

答案 1 :(得分:2)

  1. 没有objA.a,可以访问内部B()构造函数,其中A :: a是可见的,因此只能作为“a”访问。

  2. B :: a在内存中引用相同的地址,B :: a没有新的静态变量,它可以通过&amp; B :: a来检查。

  3. 预计不会是3和3,因为行“B obj”,预计为3和4;更改A :: a值,因为(2)它与B :: a的变量相同(即B()构造函数更改A :: a)。

答案 2 :(得分:1)

您的根本问题是您错误地解释了您链接的问题中的答案。当您派生课程B时,您制作新的静态变量a

因此,A::aB::a是同一个变量。一旦你纠正了这种误解,其他一切都将是显而易见的。

查看您的代码:

A objA; //A() executes which sets A::a to 3
cout << "Before:" << A::a; //outputs 3
B obj; //now B() executes and sets B::a to 4
cout << endl << "After:" << A::a; //outputs 4 since A::a is same variable as B::a

  

如何取代A :: a我还可以访问objA.a?

因为语言规范说你可以。语言规范说A::aobjA.a是同一个变量。任何良好的语言指南都包含这一点。例如,在线您可以阅读cppreference.com,其内容如下:

  

要引用类T的静态成员n,可以使用两种形式:限定名称T :: m或成员访问表达式em或e-&gt; m,其中e是计算结果为T或T *的表达式分别。在相同的班级范围内,不需要资格。

答案 3 :(得分:0)

  1. 可以通过该类的对象访问静态变量。为什么他们不是?
  2. 任何静态变量只有一个副本。如果另一个类继承它,它只能访问相同的静态变量,而不是另一个副本。
  3. 由于B::B()已将A::a更改为4. BA共享A::a的访问权限。

答案 4 :(得分:0)

  

是否继承了静态成员?

从某种意义上说,基类的静态成员也是任何派生类的静态成员,是的。

  

如何代替A::a我还可以访问objA.a。静态变量不应该通过该类的对象访问。

这就是语言的定义方式。两者都是等价的,如果你不能轻易地写出对象的类型,那么对象样式会更方便。

  

如果派生类也是一个新的静态变量(特定于B类)那么为什么没有必要为B类初始化静态变量?

没有特定于类B的新静态变量;班级A只有一个。继承意味着它也在类B范围内;但是A::aB::a都指的是同一个变量。

  

为什么下面的输出显示为[3,4],当它预期显示为3之前和之后?

如上所述,只有一个变量,B的构造函数将其设置为4