FLTK C ++ Fl_line不会画画

时间:2017-09-27 09:24:28

标签: c++ fltk

我的任务是调试一个代码,该代码用于使用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 p{Point{100, 100}, Point{100, 200}, Point{500, 100}, Point{500, 200}};
win.Attach(p);
win.end();
win.show();
return (Fl::run());
}

2 个答案:

答案 0 :(得分:2)

让我们来看看你的MyWindow::Attach功能:

void Attach(Shape s) {
shapes.push_back(&s);
}

在函数中,参数s按值传递。这意味着它与函数内的局部变量相同。因此,一旦函数返回,它将超出范围并被破坏。

保存指向该变量的指针将导致您保存指向不存在的对象的杂散指针。取消引用该指针将导致undefined behavior,导致整个程序格式错误并无效。

解决问题的一种方法是确保对象不会超出范围。这可以通过使用智能指针来完成,例如std::unique_ptr。并且在p函数中定义变量main时已经从头开始使用它。

解决问题的另一种方法是假设传递给Shape的{​​{1}}的生命周期比Attach对象更长,因此您可以传递Shape } 通过引用

Shape

现在您不再获取void Attach(Shape& s) { shapes.push_back(&s); } 对象的副本,并将指针推送到原始对象(在您的情况下是Shape函数中的对象p)。只要原始对象处于活动状态并且在范围内,解除引用指针就会有效。

答案 1 :(得分:0)

我尝试在VS2015中运行该代码并获得大量错误(当然通过引用修复附加窗口传递)但是当我运行到linux时,它可以绘制,所以我认为你应该转移到linux。