0

当我查看下面的代码示例时,我认为d.B::num是一样的,b.num但事实并非如此。它似乎是一个不同的变量,有自己的地址。当我单击运行按钮时,我会看到三个变量中的每一个b.numd.numd.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;
}
4

2 回答 2

2

看来你有:

B[int B::num]

D[int B::num, int D::num]

如果你调用d.num它默认为D::num 如果你调用d.B::num它默认为B::num

于 2013-06-07T07:42:29.430 回答
1

有类的实例,也有类。它们是不同的东西。就像所有整数不是相同的值一样,一个类的不同实例也不是相同的值。

当派生类从基类继承时,派生类的实例在其中具有基类的实例(实际上是子实例)。

如果不使用virtual关键字,则派生类实例的那些子实例基本上是基类的完全正常的实例。当您在派生中创建与在 base 中具有相同名称的成员变量时,您所做的就是将变量隐藏在 base 的子实例中以防止随意使用。您仍然可以通过指针或对 base 的引用访问子实例隐藏变量,或者使用Base::x语法完全限定它。

尽管看起来像访问static变量,但该Base::x语法也用于引用 base 中可能隐藏在 derived 中的事物的名称,即使它们不是static.

我提到这仅适用于非virtual案例。现在,virtual基中的方法可以在派生中被覆盖。您可以将virtual方法视为指向实际方法的指针,存储在 base: wben 您构造派生实例时,它会更改派生实例的基子对象的virtual方法指针指向的派生方法。在那之后,即使你有一个指向基址的指针,调用virtual方法也可以调用派生方法。

的另一个用途virtual是当你继承时。如果您不使用 继承virtual,则就像基类实例在实例的“开始”处按继承顺序描述的顺序连接。如果您继承 with virtual,则会有一个偏移量表,说明基本实例相对于派生对象的位置。这一点很重要,因为您可以在给定的派生中拥有多个 base 子实例,而无需继承virtual,但只有一个 wirhvirtual继承。

上述某些内容并不完全符合标准的规定,而是编译器出于说明目的可能如何实现标准。

于 2013-06-07T08:23:04.610 回答