当我查看以下代码示例时,我认为d.B::num
与b.num
相同,但事实并非如此。它似乎是一个具有自己地址的不同变量。当我点击运行按钮时,我看到三个变量b.num
,d.num
和d.B::num
中的每一个都有其相关值(分别为3,4和5)。
为什么会这样?这里d.B::num
究竟是什么,如果它与b.num
不一样?
struct B {int num;};
struct D : public B {int num;};
int main() {
B b;
D d;
b.num = 3;
d.num = 4;
d.B::num = 5;
cout << b.num << endl;
cout << d.num << endl;
cout << d.B::num << endl;
return 0;
}
答案 0 :(得分:2)
好像你有:
B[int B::num]
和
D[int B::num, int D::num]
如果您致电d.num
,则默认为D::num
如果您致电d.B::num
,则默认为B::num
答案 1 :(得分:1)
有类的实例,还有类。他们是不同的东西。就像所有整数不是相同的值一样,类的不同实例不是相同的值。
当派生类继承自基类时,派生类的实例会在其中包含基类的实例(实际上是子实例)。
如果没有使用virtual
关键字,那么派生类实例的那些子实例基本上是基类的完全正常实例。当您在基础中创建与派生相同名称的成员变量时,您所做的只是隐藏基础的子实例中的变量来自临时使用。您仍然可以通过指针或对base的引用来访问子实例隐藏变量,或者使用Base::x
语法对其进行完全限定。
尽管看起来像访问static
变量,Base::x
语法也用于引用基础中可能隐藏在派生中的事物的名称,即使它们不是static
我提到这只适用于非virtual
个案例。现在,base中的virtual
方法可以在派生中重写。您可以将virtual
方法视为指向实际methid的指针,存储在base:wben中构造派生实例,它会更改派生实例的基础子对象的virtual
方法指针指向的内容衍生方法。在那之后,即使你有一个指向base的指针,调用virtual
方法也可以调用派生方法。
virtual
的使用是你继承的。如果继承没有virtual
,就像基类实例按照继承顺序所描述的顺序连接在实例的“开始”。如果继承virtual
,则会有一个偏移表,说明基本实例相对于派生对象的位置。这一点非常重要,因为在没有virtual
的情况下,您可以在给定的派生中拥有多个基础子实例,但只有一个wirh virtual
继承。
上述某些内容并不完全符合标准,而是编译器如何为说明目的实施标准。