问题是: 画一个圆角的方框。定义一个类Box,由四行和四个弧组成。 所以我为这个练习编写了以下代码:
#include <Simple_window.h>
Simple_window win(Point(100,100), 600,400, "semi-ellipse");
struct Box: Shape{
Box(Point p, int ww, int hh): w(ww), h(hh)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
win.attach(hrz1);
win.attach(hrz2);
win.attach(ver1);
win.attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
private:
int w;
int h;
};
int main()
{
using namespace Graph_lib;
Box b(Point(100,100),100,50);
win.attach(b);
win.wait_for_button();
}
当我跑步时,我遇到了这个例外:
test.exe中0x757FE9D7(ole32.dll)的未处理异常:0xC0000005:访问冲突读取位置0x00000004。
我知道这是指在全球状态下声明Simple_window win(Point(100,100), 600,400, "semi-ellipse");
。但我这样做是因为我不得不这样做。问题是如何在任一部分(b
函数和Simple_window win
struct)中将行和对象(此处main()
)附加到Box
。
答案 0 :(得分:1)
看起来它是由全球创造的胜利引起的。我从未运行过FLTK程序,其中在main之前创建了任何图形,但我猜测有时图形库需要一些东西到位,所以最好在main之后使用它们。
你能做些什么呢?如果win被声明为指针并在main而不是main main中创建,那么你就不会发生崩溃。
...
Simple_window* win;
struct Box: Shape
{
...
win->...
...
}
int main()
{
win = new Simple_window(Point(100, 100), 600, 400, "semi-ellipse");
Box b ...
win->attach ...
win->wait ...
delete win;
}
答案 1 :(得分:1)
根本不需要在全球空间放置任何东西。您希望将信息传递给需要它们的类,而不是在使用它之前需要在全局范围内声明的所有内容。
我在这里写的内容会修改你的Box
类,以便它还有一个私有成员变量,它是指向Simple_window
类的指针。修改构造函数,以便在构造Box b
时,必须向它发送指向它将被绘制的Simple_window
的指针。执行此操作时,将为指针指定指向当时声明的Simple_Window win
。
#include <Simple_window.h>
struct Box: Shape{
private:
int w;
int h;
Simple_window* window;
public:
Box(Point p, int ww, int hh,Simple_window* win_): w(ww), h(hh),window(win_)
{ add(Point(p.x-ww,p.y-hh)); }
void d_l() const //creating 4 lines
{
Line hrz1 (Point(150,100), Point(400,100));
Line hrz2 (Point(150,300), Point(400,300));
Line ver1 (Point(507,150), Point(507,250));
Line ver2 (Point(41,150), Point(41,250));
window->attach(hrz1);
window->attach(hrz2);
window->attach(ver1);
window->attach(ver2);
}
void draw_lines() const //creating 4 arcs
{
fl_arc(point(0).x,point(0).y,w,h,30,90);
fl_arc(point(0).x,point(0).y,w,h,270,330);
fl_arc(point(0).x,point(0).y,w,h,90,150);
fl_arc(point(0).x,point(0).y,w,h,210,270);
}
};
int main()
{
using namespace Graph_lib;
Simple_window* win = new Simple_window(Point(100,100), 600,400, "semi-ellipse");
Box b(Point(100,100),100,50,win);
win->attach(b);
win->wait_for_button();
}
答案 2 :(得分:0)
您的行是硬编码的,与构造函数参数无关。它们可以直接使用FLTK库绘制,类似于弧,并放置在继承自类Shape
和覆盖函数void draw_lines() const
的内部。然后你不需要将窗口对象作为指针。
可能的实施方式是:
Box::Box(Point p, int w, int h)
: width(w), height(h)
{
add(Point(p.x - w, p.y - h));
}
void Box::draw_lines() const
{
// draw lines with reduced length to adapt for the arcs
if (color().visibility())
{
// upper horizontal
fl_line(point(0).x + width/4, point(0).y, point(0).x + (3./4.) * width, point(0).y);
// lower horizontal
fl_line(point(0).x + width/4, point(0).y + height, point(0).x + (3./4.) * width, point(0).y + height);
// left vertical
fl_line(point(0).x, point(0).y + height/4, point(0).x, point(0).y + (3./4.)*height);
// right vertical
fl_line(point(0).x + width, point(0).y + height/4, point(0).x + width, point(0).y + (3./4.) * height);
}
// draw arcs
if(color().visibility())
{
fl_color(fill_color().as_int());
// upper left arc
fl_arc(point(0).x, point(0).y, width/2, height/2, 90, 180);
// upper right arc
fl_arc(point(0).x + width/2, point(0).y, width/2, height/2, 0, 90);
// down right arc
fl_arc(point(0).x + width/2, point(0).y + height/2, width/2, height/2, 270, 0);
// down left arc
fl_arc(point(0).x , point(0).y + height/2, width/2, height/2, 180, 270);
}
}