静态成员是继承的吗?

Posted

技术标签:

【中文标题】静态成员是继承的吗?【英文标题】:Are static members inherited? 【发布时间】:2013-05-08 17:07:26 【问题描述】:

我在 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?,当创建派生类型对象时,它也会创建基类型。 我有以下问题:

    为什么我可以访问objA.a 而不是A::a?不应通过该类的对象访问静态变量。

    如果为派生类也创建了一个新的静态变量(特定于class B),那么为什么不需要为class B 初始化静态变量?

    为什么下面的输出显示为:

之前:3

之后:4

预计前后什么时候显示3?

【问题讨论】:

标题的答案取决于您对术语继承的定义是什么。 【参考方案1】:

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

【讨论】:

但这就是问题的答案吗? @user2287617:这是对标题中提出的问题的答案,但不是对正文中三个松散相关的问题的答案。 这完全是错误的。无论是否私有,所有成员都是继承的。【参考方案2】:

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

    B::a 指的是内存中的同一个地址,B::a 没有新的静态变量,可以通过 &B::a 查看。

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

【讨论】:

您确实可以使用objA.a 访问该变量。【参考方案3】:

您的根本问题是您错误地解释了您所链接问题的答案。当您派生类 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

为什么我可以访问 objA.a 而不是 A::a?

因为语言规范说你可以。语言规范说A::aobjA.a 是同一个变量。这在任何好的语言指南中都有介绍。例如,您可以在线阅读cppreference.com,它是这样写的:

要引用类 T 的静态成员 n,可以使用两种形式:限定名称 T::m 或成员访问表达式 e.m 或 e->m,其中 e 是分别计算为 T 或 T* 的表达式.在同一类范围内时,资格是不必要的。

【讨论】:

请注意,在我使用的两种情况下,我都没有使用 B::a,它的 A::a。 另请注意,将创建新的静态变量,请参阅证明它的链接。 没错 -- 没有B::a,只有 Zuul..别等,只有A::a(抱歉,@david-heffernan 的头像给了我捉鬼敢死队的闪回) @user2287617 不,没有新的静态变量。 A::aB::a 是一回事。一旦你明白这一点,你会没事的。 好。你应该接受一个答案。选择您认为最好的那个。【参考方案4】:
    可以通过该类的对象访问静态变量。为什么不呢? 任何静态变量都只有一个副本。如果另一个类继承它,它只能访问同一个静态变量,而不是另一个副本。 因为B::B()A::a 更改为4。BA 都共享对A::a 的访问权限。

【讨论】:

【参考方案5】:

静态成员是否继承?

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

为什么我可以访问objA.a 而不是A::a。不应通过该类的对象访问静态变量。

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

如果为派生类也创建了一个新的静态变量(特定于 B 类),那么为什么不需要为 B 类初始化静态变量?

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

为什么following的输出显示为[3,4],而预期在Before和after中显示为3?

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

【讨论】:

关于对象样式的使用:this-&gt;a(而不仅仅是a)可以在模板中使用,以使变量名依赖。

以上是关于静态成员是继承的吗?的主要内容,如果未能解决你的问题,请参考以下文章

在类模板中专门化非静态成员是不可能的吗?为啥?

java中私有的属性、静态成员可以被子类继承吗?

Javascript 中的私有成员。它们可以是非静态的吗?

C++派生类是不是可以从基类继承静态数据成员和静态成员函数?

如何继承静态成员?

静态类成员python