简体   繁体   English

虚函数和多态-代码说明

[英]Virtual Functions and Polymorphism - Code Explanation

#include <iostream>
using namespace std;

class GrandParent {
 public:
      int variable1;
      static int variable2;
      int virtual show() { return 10; }
};

int GrandParent :: variable2 = 9;

class Parent1 : public virtual GrandParent {
 public:
      int show() { return 1; }  
};

class Parent2 : public virtual GrandParent {
 public:
      int show() { return 9; }  
};

class Child : public Parent1, public Parent2 {
 public:
      int variable1;
      Child(){variable1 = 10; GrandParent::variable2 = 3;}
      int show() { return 7; }  
};

int main() {
      GrandParent *objGrand = new Child();
      GrandParent *objGrand1 = new Parent1();
      Parent2 *objP = new Child();
      Child *objChild = new Child();
      int a = (objGrand->show())*(objP->show())*(objChild->show())*(objGrand1->show());
      int b = (objGrand->variable1)*(objP->variable1)*(objChild->variable1);
      int c = (objGrand->variable2)*(objP->variable2)*(objChild->variable2);

      cout << a + b * c << endl;
      return 0;
}

Can someone please help me understand why (objGrand->variable1) = 0 & (objP->variable1) = 0 and not 10? 有人可以帮我理解为什么(objGrand-> variable1)= 0&(objP-> variable1)= 0而不是10吗? This is a part of an online course I am doing. 这是我正在做的在线课程的一部分。 They posted the solution and an explanation. 他们发布了解决方案和解释。 However, I did not find their explanation convincing so needed some help. 但是,我发现他们的解释没有说服力,因此需要一些帮助。

Child re-declares the member variable variable1 . Child重新声明成员变量variable1 This gives this class its own variable with that name, shadowing the variable inherited from the GrandParent class. 这为该类提供了具有该名称的自己的变量,从而遮盖了从GrandParent类继承的变量。 So when its constructor does: 因此,当其构造函数执行以下操作时:

variable1 = 10;

it's assigning to Child::variable1 , not GrandParent::variable1 . 它分配给Child::variable1 ,而不是GrandParent::variable1

Member variables aren't accessed virtually, this is only done for virtual member functions. 不能虚拟访问成员变量,这仅对virtual成员函数完成。 So if you then use 因此,如果您使用

objGrand->variable1

it refers to GrandParent::variable1 , because objGrand is GrandParent* , even though objGrand points to a Child object. 它引用GrandParent::variable1 ,因为objGrandGrandParent* ,即使objGrand指向Child对象。 Since GrandParent has no constructor that initializes variable1 , this is uninitialized, not 0 , and using it results in undefined behavior. 由于GrandParent没有初始化variable1构造函数,因此未初始化,而不是0 ,并且使用它会导致未定义的行为。

To get Child::variable1 you need to downcast it: 要获取Child::variable1您需要对其下调:

dynamic_cast<Child*>(objGrand)->variable1

The same is true for objP for the same reasons. 出于相同的原因, objP也是如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM