【问题标题】:virtual function outputting weird values虚函数输出奇怪的值
【发布时间】:2013-10-20 11:03:30
【问题描述】:

我有 2 个课程:ShapeTwoD 和 Square。 Square 派生自 ShapeTwoD。

class ShapeTwoD
 { 
   public:virtual int get_x()
          { return x;}

          void set_x(int x)
          {x = x; }

   private:
        int x;
 };


class Square:public ShapeTwoD
{    
    public:
          virtual int get_x()
          { return x+5; }

    private:
           int x;

};

在我的主程序中

int main()
{
 Square* s = new Square;

s->set_x(2);

cout<<s->get_x()  //output : 1381978708 when i am expecting 2
    <<endl;




ShapeTwoD shape[100];

shape[0] = *s;

cout<<shape->get_x(); //output always changes when i am expecting 2


}

我得到的控制台输出很奇怪。

第一个输出是 1381978708 虽然我希望它是 2 。

第二个输出总是变化,虽然我也期望它是 7

我正在尝试使用虚函数来解析到最派生的类方法, 有人可以向我解释发生了什么吗???

【问题讨论】:

  • 行为看起来相当简单;你有两个x 成员变量; set_x 正在修改基类(实际上不是,x=x 什么都不做!),get_x 正在返回(未初始化的)派生类。

标签: c++ debugging polymorphism virtual-functions


【解决方案1】:

看一下代码中的cmets:

class ShapeTwoD
{ 
public:
    virtual int get_x()
    {
        return x; // outputs ShapeTwoD::x
    }

    void set_x(int x)
    {
        // x = x;   // sets x to x
        this->x = x // sets ShapeTwoD::x
    }

   private:
        int x;
 };


class Square:public ShapeTwoD
{    
public:
    virtual int get_x()
    {
        return x + 5; // Outputs Square::x
    }

private:
    int x;
};

int main()
{
    Square* s = new Square;

    s->set_x(2);

    cout<<s->get_x()  //output : 1381978708 when i am expecting 2
        <<endl;       // because Square::x is uninitialized

    ShapeTwoD shape[100];

    shape[0] = *s; // slices Square to ShapeTwoD

    cout<<shape->get_x(); //output always changes when i am expecting 2
                          // look at the comments to the set_x function
}

所以,因为xShapeTwoD 中被声明为private,所以Square 无法访问它。你必须这样做:

  1. 使xShapeTwoD 中受保护
  2. Square 中删除x
  3. set_x 中的x = x 更改为this-&gt;x = x(或者将成员变量重命名为_x

【讨论】:

    【解决方案2】:

    这是因为每个类都有单独的x 成员。因此,当您调用s-&gt;set_x(2) 时,您将其设置在对象的ShapeTwoD 部分中,而Square::get_x 则从对象的Square 部分中获取一个。

    Square类中移除成员变量,并使ShapeTwoD中的成员变量受保护。

    【讨论】:

      【解决方案3】:

      您不需要第二个x,它在派生类的虚拟方法中隐藏基类的x,只需使用

      class Square:public ShapeTwoD
      {    
      public:
            virtual int get_x()
            { return x+5; }
      };
      

      在您的原始代码中,Square::get_x() 引用了 Square::x,而来自 ShapeTwoD 的设置器正在设置 ShapeTwoD::x

      另外,setter 本身是错误的,你想要:

      void set_x(int x)
      {
          this->x = x;
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-04-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-04
        • 2015-11-02
        相关资源
        最近更新 更多