我有两个类: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
我正在尝试使用虚函数来解析最派生的类方法, 谁能向我解释发生了什么?
答案 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
被声明为ShapeTwoD
,Square
无法访问它。你必须这样做:
x
ShapeTwoD
x
Square
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;
}