【问题标题】:Why is scope resolution not working on overridden variable?为什么范围解析不适用于覆盖的变量?
【发布时间】:2013-06-03 10:29:09
【问题描述】:

当我查看以下代码示例时,我认为 d.B::numb.num 相同,但事实并非如此。它似乎是一个不同的变量,有自己的地址。当我点击运行按钮时,我看到b.numd.numd.B::num 三个变量中的每一个都有其关联值(分别为 3、4 和 5)。

为什么会这样?如果和b.num不一样,这里的d.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;
}

【问题讨论】:

  • 但是...您有两个不同的对象:bdd.B::num 指的是 B::numd 实例中的实例。 b.num 是一个完全不同的实例的一部分。
  • db 是不同的对象,所以很明显d.B::numb.B::num 将是不同的[子] 对象(B::num 不是static)。我不确定我明白你在问什么?
  • 你不能“覆盖”变量。
  • 没有覆盖变量。 D::num 隐藏B::num。一个D 实例有两个int 数据成员,其中一个(B's)是隐藏的。所以如果你想访问它,你必须具体说明它。
  • 这只是普通的名称隐藏

标签: c++ inheritance overriding scope-resolution


【解决方案1】:

看来你有:

B[int B::num]

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

如果您调用d.num,则默认为D::num 如果您调用d.B::num,则默认为B::num

【讨论】:

  • +1(虽然我不会将最后一位称为“默认”——毕竟它涉及一个明确的范围名称)。
【解决方案2】:

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

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

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

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

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

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

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

【讨论】:

    猜你喜欢
    • 2021-10-30
    • 2017-07-03
    • 1970-01-01
    • 2016-11-22
    • 1970-01-01
    • 1970-01-01
    • 2013-09-17
    • 1970-01-01
    • 2017-10-25
    相关资源
    最近更新 更多