FLTK C++ Fl_line 不画
Posted
技术标签:
【中文标题】FLTK C++ Fl_line 不画【英文标题】:FLTK C++ Fl_line don't draw 【发布时间】:2017-09-27 09:24:28 【问题描述】:我的任务是调试一段代码,该代码旨在使用 FLTK 从 4 个点中绘制一个简单的多边形。 MyWindow
类派生自 Fl_Window
。 Shape
类是 ClosedPolyline
的父类。 MyWindow
和 Shape
都持有一个向量来绘制所有的形状。
问题是编译运行后win.show()
会打开一个没有任何绘图的空窗口。我很难理解这种行为。
这里是代码(我省略了一些与绘图无关的部分ClosedPolyline
):
#include <iostream>
#include <FL/Fl.H>
#include <FL/Fl_Draw.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Widget.H>
#include <FL/Fl_Device.H>
#include <initializer_list>
#include <vector>
#include <functional>
//#include <cmath>
//#include <math.h>
struct Point
int x,y;
Point(int xx, int yy) : x(xx), y(yy)
;
class Shape
public:
Point point(int idx) const
return (points[idx]);
unsigned int points_size() const
return points.size();
void draw() /*const*/
draw_lines();
void add(Point p) points.push_back(p);
protected:
virtual void draw_lines()
private:
std::vector<Point> points;
;
class ClosedPolyline: public Shape
public:
/*ClosedPolyline(std::initializer_list<Point> pp)
if (pp.size() > 0)
for (Point p: pp)
add(p);
*/
ClosedPolyline(Point a1, Point a2, Point a3, Point a4)
add(a1); add(a2); add(a3); add(a4);
protected:
void draw_lines() override
for (unsigned int i=1; i<points_size(); ++i)
fl_line(point(i-1).x, point(i-1).y, point(i).x, point(i).y);
;
class MyWindow: public Fl_Window
public:
MyWindow(int x, int y, int w, int h, const char* title = 0)
: Fl_Window(x, y, w, h, title)
void Attach(Shape s)
shapes.push_back(&s);
//void draw_shapes()draw();
protected:
void draw() override
for(Shape * s: shapes)
s->draw();
//s.draw();
private:
std::vector<Shape*> shapes;
;
这里是main()
函数:
int main()
MyWindow win(100, 100, 600, 400, "C++ Test task");
ClosedPolyline pPoint100, 100, Point100, 200, Point500, 100, Point500, 200;
win.Attach(p);
win.end();
win.show();
return (Fl::run());
【问题讨论】:
【参考方案1】:让我们看看你的MyWindow::Attach
函数:
void Attach(Shape s)
shapes.push_back(&s);
在函数中,参数s
是按值传递的。这意味着它与函数内部的 局部变量 相同。因此,一旦函数返回,它将超出范围并被破坏。
保存指向该变量的指针将导致您保存一个杂散指针,指向一个不存在的对象。取消引用该指针将导致undefined behavior,使您的整个程序格式错误且无效。
解决问题的一种方法是确保对象不会超出范围。这可以通过使用 智能指针 来完成,例如std::unique_ptr
。当您在 main
函数中定义变量 p
时,从一开始就使用它。
解决您的问题的另一种方法是假设传递给Attach
的Shape
的生命周期比Shape
对象的寿命长,因此您可以通过引用传递Shape
em>:
void Attach(Shape& s)
shapes.push_back(&s);
现在您不再获得Shape
对象的副本,而是将指针推送到原始对象(在您的情况下,main
函数中的对象p
)。只要原始对象处于活动状态且在范围内,取消引用指针就会有效。
【讨论】:
我明白你的意思。但是,我被禁止修改main()
函数,所以我认为为了达到相同的结果,我可以用形状的副本填充向量并使用这些副本调用 draw()
。然而,结果仍然是一样的,一个空白窗口。这是编辑后的MyWindow()
:
@NgocDuyNguyen 问题是复制正在创建一个Shape
对象,请注意ClosedPolyline
对象。虽然Shape
对象将具有来自原始的Point
向量,但它有一个空的draw_lines
函数,它什么都不做。正是你的行为。
@NgocDuyNguyen 用另一种可能的解决方案更新了我的答案。
谢谢。我觉得自己像个笨蛋,因为在问之前没有深入思考。但是,在向量中前 2 个点的第一条线被绘制之后,我得到了异常 SIGSEGV
。我已经确保向量的偏移量没有超出范围。搜索此异常并没有给我太多关于为什么会在这种情况下发生的答案。
你能解释一下为什么不管我调用fl_line()
的顺序是什么,它总是在绘制第一行后崩溃并出现分段错误(SIGSEGV
)。我使用了一个 for 循环来打印向量中的所有值以说明它们在界限内,因此我想不出任何其他可能触发此异常的因素。这是我编辑的代码:pastebin.com/ueMMvLf5。会不会是编译器错误? (我正在使用 FLTK 1.3.4 在 MinGW 中构建)【参考方案2】:
我尝试在 VS2015 中运行该代码并得到很多错误(当然通过引用修复附加窗口传递)但是当我运行到 linux 时,它可以绘制,所以我认为你应该转移到 linux。
【讨论】:
哇,谢谢。我从来不知道差异会如此激进。您是否在我的评论中使用@Someprogrammerdude 或问题中的上述代码运行了修复程序?我还没有 linux(还),所以如果你能在那里为我测试一下,我将不胜感激。 我已经设法解决了第二个问题,这里有一个解决方案***.com/questions/46460759/…以上是关于FLTK C++ Fl_line 不画的主要内容,如果未能解决你的问题,请参考以下文章