需要帮助将类重构为单独的头文件和 cpp 文件

Posted

技术标签:

【中文标题】需要帮助将类重构为单独的头文件和 cpp 文件【英文标题】:Need help refactoring class into separate header and cpp files 【发布时间】:2020-08-09 23:13:38 【问题描述】:

谁能将MyWindow 类从这个出色的FLTKexample 中拆分为单独的MyWindow.hMyWindow.cpp 文件?

我已经尝试了整个下午。我被困在Fl::add_timeout 方法中的(void*)this 部分。我确定我还有其他问题。

我想看看如何最好地处理递归。你是MyWindow::RenderImage_CB还是留下RenderImage_CB

为方便起见,在此处添加代码。

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include <time.h>

#define XSIZE 500
#define YSIZE 500
#define UPDATE_RATE 0.05     // update rate in seconds

// Demonstrate how to display a pixel buffer in FLTK

// WINDOW CLASS TO HANDLE DRAWING IMAGE
class MyWindow : public Fl_Double_Window 
    unsigned char pixbuf[YSIZE][XSIZE][3];              // image buffer

    // FLTK DRAW METHOD
    void draw() 
        fl_draw_image((const uchar*)&pixbuf, 0, 0, XSIZE, YSIZE, 3, XSIZE*3);
    

    // TIMER CALLBACK: CALLED TO UPDATE THE DRAWING
    static void RenderImage_CB(void *userdata) 
        MyWindow *win = (MyWindow*)userdata;
        win->RenderImage();
        Fl::repeat_timeout(UPDATE_RATE, RenderImage_CB, userdata);
    

public:
    // CTOR
    MyWindow(int w, int h, const char *name=0) : Fl_Double_Window(w,h,name) 
        end();
        RenderImage();                   // show first drawing
        // Start timer updating
        Fl::add_timeout(UPDATE_RATE, RenderImage_CB, (void*)this);
    

    // PLOT A PIXEL AS AN RGB COLOR INTO THE PIXEL BUFFER
    void PlotPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b) 
        pixbuf[y][x][0] = r;
        pixbuf[y][x][1] = g;
        pixbuf[y][x][2] = b;
    

    // MAKE A NEW PICTURE IN THE PIXEL BUFFER, SCHEDULE FLTK TO DRAW IT
    void RenderImage() 
        static unsigned char drawcount = 0;
        for ( int x=0; x<XSIZE; x++ )
            for ( int y=0; y<YSIZE; y++ )
                PlotPixel(x, y, x+drawcount, y+drawcount, x+y+drawcount);
        ++drawcount;
        redraw();
    
;

int main(int argc, char**argv) 
    Fl::visual(FL_RGB);         // prevents dithering on some systems
    MyWindow *win = new MyWindow(XSIZE, YSIZE);
    win->show();
    return(Fl::run());

这样分隔会产生编译错误:

main.cpp

#include "MyWindow.h"

int main(int argc, char**argv) 
    Fl::visual(FL_RGB);         // prevents dithering on some systems
    MyWindow *win = new MyWindow(XSIZE, YSIZE);
    win->show();
    return(Fl::run());

MyWindow.h

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include <time.h>

#define XSIZE 500
#define YSIZE 500
#define UPDATE_RATE 0.05     // update rate in seconds

// WINDOW CLASS TO HANDLE DRAWING IMAGE
class MyWindow : public Fl_Double_Window 
    unsigned char pixbuf[YSIZE][XSIZE][3];              // image buffer

    // FLTK DRAW METHOD
    void draw();

    // TIMER CALLBACK: CALLED TO UPDATE THE DRAWING
    void RenderImage_CB(void *userdata);

public:
    // CTOR
    MyWindow(int w, int h, const char *name=0) : Fl_Double_Window(w,h,name);

    // PLOT A PIXEL AS AN RGB COLOR INTO THE PIXEL BUFFER
    void PlotPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b);

    // MAKE A NEW PICTURE IN THE PIXEL BUFFER, SCHEDULE FLTK TO DRAW IT
    void RenderImage();
;

MyWindow.cpp

#include "MyWindow.h"

void MyWindow::draw() 
    fl_draw_image((const uchar*)&pixbuf, 0, 0, XSIZE, YSIZE, 3, XSIZE*3);


void MyWindow::RenderImage_CB(void *userdata) 
    MyWindow *win = (MyWindow*)userdata;
    win->RenderImage();
    Fl::repeat_timeout(UPDATE_RATE, MyWindow::RenderImage_CB, userdata);


MyWindow::MyWindow(int w, int h, const char *name) : Fl_Double_Window(w,h,name) 
    end();
    MyWindow::RenderImage();                   // show first drawing
    // Start timer updating
    Fl::add_timeout(UPDATE_RATE, MyWindow::RenderImage_CB, (void*)this);


void MyWindow::PlotPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b) 
    pixbuf[y][x][0] = r;
    pixbuf[y][x][1] = g;
    pixbuf[y][x][2] = b;


void MyWindow::RenderImage() 
    static unsigned char drawcount = 0;
    for ( int x=0; x<XSIZE; x++ )
        for ( int y=0; y<YSIZE; y++ )
            PlotPixel(x, y, x+drawcount, y+drawcount, x+y+drawcount);
    ++drawcount;
    redraw();

使用上面我的第一个错误是:

MyWindow.cpp:10:71: error: no matching function for call to 'Fl::repeat_timeout(double, <unresolved overloaded function type>, void*&)'
     Fl::repeat_timeout(UPDATE_RATE, MyWindow::RenderImage_CB, userdata);

【问题讨论】:

到目前为止您尝试过什么?这个过程应该是机械的和直接的;其中一个成员函数是static这一事实并没有太大的区别。将类定义复制到头文件中。在标题中,删除所有定义并用分号替换。在cpp文件中,去掉周围的class、数据成员的声明和public/private,在所有函数上加上MyClass::,并从声明中去掉static 解决方案取决于您的需要。最简单的答案是将整个类声明移动到 .h 文件中。包含它的所有模块都将使用相同的声明。但是,这隐式地使所有方法都内联。如果你不喜欢这样,就按照 Thomas 上面说的做:在 .h 中放置一个包含所有方法声明的类声明,在 .cpp 文件中放置方法定义。 【参考方案1】:

编译并运行:

main.cpp

#include "MyWindow.h"

int main(int argc, char**argv) 
    Fl::visual(FL_RGB);         // prevents dithering on some systems
    MyWindow *win = new MyWindow(XSIZE, YSIZE);
    win->show();
    return(Fl::run());

MyWindow.h

#include <FL/Fl.H>
#include <FL/Fl_Double_Window.H>
#include <FL/fl_draw.H>
#include <stdio.h>
#include <time.h>

#define XSIZE 500
#define YSIZE 500
#define UPDATE_RATE 0.05     // update rate in seconds

// WINDOW CLASS TO HANDLE DRAWING IMAGE
class MyWindow : public Fl_Double_Window 
    unsigned char pixbuf[YSIZE][XSIZE][3];              // image buffer

    // FLTK DRAW METHOD
    void draw();

    // TIMER CALLBACK: CALLED TO UPDATE THE DRAWING
    static void RenderImage_CB(void *userdata);

public:
    // CTOR
    MyWindow(int w, int h, const char *name=0);// : Fl_Double_Window(w,h,name);

    // PLOT A PIXEL AS AN RGB COLOR INTO THE PIXEL BUFFER
    void PlotPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b);

    // MAKE A NEW PICTURE IN THE PIXEL BUFFER, SCHEDULE FLTK TO DRAW IT
    void RenderImage();
;

MyWindow.cpp

#include "MyWindow.h"

MyWindow::MyWindow(int w, int h, const char *name) : Fl_Double_Window(w,h,name) 
    end();
    MyWindow::RenderImage();                   // show first drawing
    // Start timer updating
    Fl::add_timeout(UPDATE_RATE, MyWindow::RenderImage_CB, (void*)this);


void MyWindow::draw() 
    fl_draw_image((const uchar*)&pixbuf, 0, 0, XSIZE, YSIZE, 3, XSIZE*3);


void MyWindow::RenderImage_CB(void *userdata) 
    MyWindow *win = (MyWindow*)userdata;
    win->RenderImage();
    Fl::repeat_timeout(UPDATE_RATE, MyWindow::RenderImage_CB, userdata);


void MyWindow::PlotPixel(int x, int y, unsigned char r, unsigned char g, unsigned char b) 
    pixbuf[y][x][0] = r;
    pixbuf[y][x][1] = g;
    pixbuf[y][x][2] = b;


void MyWindow::RenderImage() 
    static unsigned char drawcount = 0;
    for ( int x=0; x<XSIZE; x++ )
        for ( int y=0; y<YSIZE; y++ )
            PlotPixel(x, y, x+drawcount, y+drawcount, x+y+drawcount);
    ++drawcount;
    redraw();

【讨论】:

以上是关于需要帮助将类重构为单独的头文件和 cpp 文件的主要内容,如果未能解决你的问题,请参考以下文章

C++ 结构原型在单独的头文件中

CodeBlocks 17.12 工程如何引用其他文件夹的头文件和源程序

解决QT单独添加ui文件后cpp文件的报错问题

将 C++ 嵌套类分离到它们自己的头文件中

CPP 将类写入/读取到二进制文件中

Code::Blocks 中的头文件和源文件问题