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_WindowShape 类是 ClosedPolyline 的父类。 MyWindowShape 都持有一个向量来绘制所有的形状。

问题是编译运行后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 时,从一开始就使用它。


解决您的问题的另一种方法是假设传递给AttachShape 的生命周期比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 不画的主要内容,如果未能解决你的问题,请参考以下文章

在 C++ 中使用 FLTK 的简单电话簿

FLTK:重写 FL_box 构造函数。 C++

C++ FLTK 1.30 MSVCR120.dll 丢失

使用 FLTK 在形状中填充颜色的 C++ 不适用于圆形

Makefile 结合了 fltk 和 C++ 文件

如何在 C++ 和 FLTK 中实现倒计时时钟?