静态成员是继承的吗?
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::a
和 B::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::a
和objA.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::a
和 B::a
是一回事。一旦你明白这一点,你会没事的。
好。你应该接受一个答案。选择您认为最好的那个。【参考方案4】:
-
可以通过该类的对象访问静态变量。为什么不呢?
任何静态变量都只有一个副本。如果另一个类继承它,它只能访问同一个静态变量,而不是另一个副本。
因为
B::B()
将A::a
更改为4。B
和A
都共享对A::a
的访问权限。
【讨论】:
【参考方案5】:静态成员是否继承?
从某种意义上说,基类的静态成员也是任何派生类的静态成员,是的。
为什么我可以访问
objA.a
而不是A::a
。不应通过该类的对象访问静态变量。
这就是语言的定义方式。两者是等价的,如果不能轻易写出对象的类型,对象样式会更方便。
如果为派生类也创建了一个新的静态变量(特定于 B 类),那么为什么不需要为 B 类初始化静态变量?
没有特定于类B
的新静态变量; A
类只有一个。继承意味着它也在类B
内;但是A::a
和B::a
都引用同一个变量。
为什么following的输出显示为[3,4],而预期在Before和after中显示为3?
如上所述,变量只有一个,B
的构造函数将其设置为4
。
【讨论】:
关于对象样式的使用:this->a
(而不仅仅是a
)可以在模板中使用,以使变量名依赖。以上是关于静态成员是继承的吗?的主要内容,如果未能解决你的问题,请参考以下文章