C++ FLTK, создание закругленного прямоугольника

Задача гласит: Нарисуйте прямоугольник со скругленными углами. Определите класс 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();
}

Когда я запустил его, я столкнулся с этим исключением:

Необработанное исключение по адресу 0x757FE9D7 (ole32.dll) в test.exe: 0xC0000005: место чтения нарушения прав доступа 0x00000004.

Я знаю, что это относится к объявлению Simple_window win(Point(100,100), 600,400, "semi-ellipse"); в глобальном состоянии. Но я сделал это, потому что должен был это сделать. Проблема в том, как прикрепить строки, а также объект (здесь b) к Simple_window win в любой части (функция main(), а также Box структура).


person zhiar    schedule 08.05.2014    source источник
comment
Нет ответа от этих многочисленных экспертов по C++!!?   -  person zhiar    schedule 08.05.2014
comment
Без исходного кода Simple_window мы просто не сможем вам помочь. Point и Shape — это тоже классы, которые пришли откуда-то еще, а не из FLTK.   -  person DejanLekic    schedule 08.05.2014
comment
Я знаю, что вы хотите сделать, но, пожалуйста, подождите меню. Меня не учили читать исходники этих файлов!!! Да. Меня учили просто использовать их, чтобы решить эту проблему. Что мне нужно от вас, так это прочитать контекст упражнения и проверить, правильно ли я понял проблему, и если да, то, пожалуйста, дайте, если у вас есть какое-либо другое решение. Спасибо.   -  person zhiar    schedule 08.05.2014
comment
Предложите вам научиться пользоваться отладчиком и выяснить, где ваша программа падает, или хотя бы рассказать нам, как выглядит стек вызовов, если вы не можете его понять.   -  person cup    schedule 09.05.2014
comment
Моя программа падает только со строки Simple window (вторая строка кода). Кубик, не уходи далеко, ответ рядом. Если вы можете сказать, как использовать win в двух телах (здесь класс main() и Box), проблема будет решена. Как раз этот случай.   -  person zhiar    schedule 10.05.2014
comment
Что такое Simple_Window? Мы не можем сказать вам, как что-либо делать, если не знаем, с чем вы играете.   -  person cup    schedule 12.05.2014
comment
Simple_Window не от FLTK. Это из книги Бьярн С.... Не распространяйте ложную информацию.   -  person DejanLekic    schedule 13.05.2014
comment
ХОРОШО. Я сделал эту маленькую ошибку. Я смог найти проблему этого кода. Если вы хотите помочь, взгляните на stackoverflow.com/questions/23625031/   -  person zhiar    schedule 13.05.2014


Ответы (3)


Похоже, это вызвано глобальным созданием win. Я никогда не запускал программу FLTK, в которой что-либо графическое создается до основного, но я предполагаю, что иногда графические библиотеки требуют, чтобы некоторые вещи были на месте, поэтому лучше использовать их после основного.

Что вы можете с этим поделать? Если win объявлен как указатель и создается внутри 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;
}
person cup    schedule 28.09.2014

Вам вообще не нужно ничего помещать в глобальное пространство. Вы хотите передавать информацию тем классам, которые в ней нуждаются, а не нуждаться во всем, объявленном в глобальной области видимости, прежде чем что-либо с этим делать.

То, что я здесь пишу, модифицирует ваш класс 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();
}
person user3353819    schedule 21.10.2014

Ваши строки жестко запрограммированы и не зависят от параметров конструктора. Их можно было нарисовать напрямую из библиотеки 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); 
    }
}
person Ziezi    schedule 20.01.2017