我在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?制作派生类型对象时,它还会创建基本类型。 我有以下问题:
如何而不是A::a
我还可以访问objA.a
?不应通过该类的对象访问静态变量。
如果派生类也是一个新的静态变量(特定于class B
)那么为什么没有必要初始化class B
的静态变量?
为什么以下输出显示为:
在:3
之后:4
预计在之前和之后显示3?
答案 0 :(得分:3)
对静态变量的访问是继承的。请注意,无法访问具有私有访问权限的静态成员,因为这是protected
关键字的用途。
答案 1 :(得分:2)
没有objA.a,可以访问内部B()构造函数,其中A :: a是可见的,因此只能作为“a”访问。
B :: a在内存中引用相同的地址,B :: a没有新的静态变量,它可以通过&amp; B :: a来检查。
预计不会是3和3,因为行“B obj”,预计为3和4;更改A :: a值,因为(2)它与B :: a的变量相同(即B()构造函数更改A :: a)。
答案 2 :(得分:1)
您的根本问题是您错误地解释了您链接的问题中的答案。当您派生课程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
如何取代A :: a我还可以访问objA.a?
因为语言规范说你可以。语言规范说A::a
和objA.a
是同一个变量。任何良好的语言指南都包含这一点。例如,在线您可以阅读cppreference.com,其内容如下:
要引用类T的静态成员n,可以使用两种形式:限定名称T :: m或成员访问表达式em或e-&gt; m,其中e是计算结果为T或T *的表达式分别。在相同的班级范围内,不需要资格。
答案 3 :(得分:0)
B::B()
已将A::a
更改为4. B
和A
共享A::a
的访问权限。答案 4 :(得分:0)
是否继承了静态成员?
从某种意义上说,基类的静态成员也是任何派生类的静态成员,是的。
如何代替
A::a
我还可以访问objA.a
。静态变量不应该通过该类的对象访问。
这就是语言的定义方式。两者都是等价的,如果你不能轻易地写出对象的类型,那么对象样式会更方便。
如果派生类也是一个新的静态变量(特定于B类)那么为什么没有必要为B类初始化静态变量?
没有特定于类B
的新静态变量;班级A
只有一个。继承意味着它也在类B
范围内;但是A::a
和B::a
都指的是同一个变量。
为什么下面的输出显示为[3,4],当它预期显示为3之前和之后?
如上所述,只有一个变量,B
的构造函数将其设置为4
。