虚函数输出奇怪的值

时间:2013-10-20 11:03:30

标签: c++ debugging polymorphism virtual-functions

我有两个类:ShapeTwoD&广场。 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

我正在尝试使用虚函数来解析最派生的类方法, 谁能向我解释发生了什么?

3 个答案:

答案 0 :(得分:1)

这是因为每个班级都有独立的x成员。因此,当您致电s->set_x(2)时,您要在对象的ShapeTwoD部分进行设置,而Square::get_x则会从对象的Square部分中提取该部分。

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

答案 1 :(得分:1)

查看代码中的注释:

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
}

因此,由于x中的private被声明为ShapeTwoDSquare无法访问它。你必须这样做:

  1. x
  2. 中保护ShapeTwoD
  3. x
  4. 移除Square
  5. x = x中的set_x更改为this->x = x(或将成员变量重命名为_x

答案 2 :(得分:0)

您不需要第二个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;
}