我从基类Octagon
类创建了一个派生的Shape
类(由Stroustrup ...使用编程原理和实践编写)。构造函数和其他方法看起来很好,除了调用修改类成员的函数不会改变任何东西。
这是我写的派生类(在基类接口之后):
class Octagon : public Shape
{
public:
Octagon(Point centre, int side_length);
double cot(double x) const{return (cos(x) / sin(x));}
void draw_lines() const;
void set_side(int x) { s_l = x; } //am i missing something?
double rad(int side){return (0.5*side*cot(PI / 8));}
private:
int s_l;
};
Octagon::Octagon(Point centre, int side_length)
:s_l( side_length )
{
for (int ang = 22.5; ang <= 337.5; ang += 45)
{
add(Point{ int(centre.x + rad(s_l) * cos(ang*PI / 180)),
int(centre.y - rad(s_l) * sin(ang*PI / 180)) });
};
}
当我在主函数中调用它时,set_side(int)
函数实际上没有做任何事情......
int main()
{
Simple_window win{ Point{100,100}, 1200, 900, "window" }; //Simple_window class
//designed by Stroustrup to display Shape objects
Octagon oct{ Point(600,450), 100};
oct.set_color(Color::black);
oct.set_side(20); //supposed to change the side length from 100 to 20
//but it stays at 100 when i run the program
win.attach(oct); //attaches Shape object to Simple_window
win.wait_for_button();
}
我不知道这是否是必要的,但这是Stroustrup使用FLTK GUI库设计的基类Shape
类。
class Shape { // deals with color and style, and holds sequence of lines
public:
void draw() const; // deal with color and draw lines
virtual void move(int dx, int dy); // move the shape +=dx and +=dy
void set_color(Color col) { lcolor = col; }
Color color() const { return lcolor; }
void set_style(Line_style sty) { ls = sty; }
Line_style style() const { return ls; }
void set_fill_color(Color col) { fcolor = col; }
Color fill_color() const { return fcolor; }
Point point(int i) const { return points[i]; } // read only access to points
int number_of_points() const { return int(points.size()); }
virtual ~Shape() { }
protected:
Shape();
virtual void draw_lines() const; // draw the appropriate lines
void add(Point p); // add p to points
void set_point(int i,Point p); // points[i]=p;
private:
vector<Point> points; // not used by all shapes
Color lcolor; // color for lines and characters
Line_style ls;
Color fcolor; // fill color
Shape(const Shape&); // prevent copying
Shape& operator=(const Shape&);
};
顺便说一句,draw_lines()
由draw()
调用,由显示引擎调用。(我逐章跟随这本书,所以我还没有到达他完全讨论这一章的章节)。
答案 0 :(得分:4)
您只在构造函数中使用 s_l
。您可以稍后将其设置为其他值,但工作已经完成。你想删除所有点并重新计算它们吗?如果是这样,你需要做它,它不会神奇地发生。
答案 1 :(得分:4)
问题是形状点是在构造函数中计算的,并且从不重置。当为s_l
设置新值时,马不在谷仓中:形状的点不会在考虑s_l
的新值的情况下重建。
更改setter以将点重置为新值以使其正常工作:
void set_side(int x) {
s_l = x;
int pos = 0;
for (double ang = 22.5 ; ang <= 337.5 ; ang += 45) {
set_point(pos++, Point {
int(centre.x + rad(s_l) * cos(ang*PI / 180))
, int(centre.y - rad(s_l) * sin(ang*PI / 180))
});
};
}
请注意,上面的ang
应该是double
,而不是int
。
答案 2 :(得分:2)
显然,在你修改了s_l后,你永远不会重新计算分数。一个简单的解决方案是将点创建代码从构造函数移动到一个单独的方法,该方法从构造函数和set_side中调用(后者应该首先删除以前存在的点)。或者,如果它足够简单,你可以修改set_side()中的现有点。