9

我有两个班级,这是其中之一的标题:

#ifndef WRAPPER_HPP
#define WRAPPER_HPP

#include <SDL/SDL.h>

using namespace std;

class Wrapper
{
  private:
    //SDL_Surface *screen;

  public:
    static SDL_Surface *screen;

    static void set_screen(SDL_Surface *_screen);
    static void set_pixel(int x, int y, Uint8 color);
    static void clear_screen(int r, int g, int b);
    static SDL_Surface* load_image(char path[500]);
    static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
    static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};

#endif

我正在从另一个文件中调用 Wrapper::set_screen(screen) 并收到此错误:

In file included from /home/david/src/aships/src/Wrapper.cpp:6:0:
/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_screen(SDL_Surface*)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:10:3: error: from this location

对于 Wrapper.cpp 上的每个函数的定义,我也遇到了类似的错误,例如:

void Wrapper::set_pixel(int x, int y, Uint8 color)
{
  /* Draws a pixel on the screen at (x, y) with color 'color' */
  Uint8 *p;
  p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
  *p = color;
}

编译时:

/home/david/src/aships/src/Wrapper.hpp: In static member function ‘static void Wrapper::set_pixel(int, int, Uint8)’:
/home/david/src/aships/src/Wrapper.hpp:11:18: error: invalid use of member ‘Wrapper::screen’ in static member function
/home/david/src/aships/src/Wrapper.cpp:17:17: error: from this location

我知道它与静态类有关,因此变量 Wrapper.screen 不可访问或其他什么,但我不确定如何修复它。有任何想法吗?

4

3 回答 3

9

您正在使用静态变量

static SDL_Surface *screen;

在你的代码中。

在 C++ 中,当您在 .h(或 .hpp)中声明静态变量时,您正在创建一个对类通用(静态)的变量。因此,要在另一个文件中使用它,您必须重新声明它(我猜您没有)以在该文件中创建一个引用静态变量的变量。在你的情况下,把这个:

SDL_Surface* Wrapper::screen;

.cpp 文件中。

我不确定这个理论是否得到很好的解释,但它是这样工作的。

于 2013-06-30T16:25:27.357 回答
1

您的类和成员(屏幕)不是静态的,这意味着它们实际上并不存在。您不能访问静态函数中的非静态成员。

尝试使您的数据成员是静态的。

于 2013-06-30T15:29:01.860 回答
0

I'm not convinced that the code abstract you show us is an accurate characterization of your problem.

Your header should not include using namespace std; — it doesn't use or declare anything from the std namespace, and specifying using namespace std; is generally regarded as 'not a good idea', doubly so when it appears in a header file.

It also isn't clear that your header needs to include SDL/SDL.h. If the Uint8 type is easily isolated (not necessarily valid), then your header file can simply use a forward declaration of the SDL_Surface class. (Your implementation code will need to include SDL/SDL.h; but you should not burden the users of your wrapper class with unnecessary #include directives when simple forward declarations would suffice.)

This code is self-contained (does not need any headers), but more or less simulates what you could use, and it compiles OK:

#ifndef WRAPPER_HPP
#define WRAPPER_HPP

typedef unsigned char Uint8;
class SDL_Surface;

class Wrapper
{
public:
    static SDL_Surface *screen;

    static void set_screen(SDL_Surface *_screen);
    static void set_pixel(int x, int y, Uint8 color);
    static void clear_screen(int r, int g, int b);
    static SDL_Surface *load_image(char path[500]);
    static void draw_image(SDL_Surface *img, int x, int y, int width, int height);
    static void draw_line(int x1, int y1, int x2, int y2, Uint8 color);
};

#endif

//#include <SDL/SDL.h>

typedef unsigned short Uint16;

class SDL_Surface
{
public:
    Uint8   *pixels;
    Uint16   pitch;
    struct
    {
        Uint8 BytesPerPixel;
    }       *format;
};

// End of SDL/SDL.h

void Wrapper::set_pixel(int x, int y, Uint8 color)
{
    /* Draws a pixel on the screen at (x, y) with color 'color' */
    Uint8 *p;
    p = (Uint8 *) screen->pixels + y * screen->pitch + x * screen->format->BytesPerPixel;
    *p = color;
}

It also compiles without warnings. The (Uint8 *) cast (copied from the original) is unnecessary. With the class definition given, it is superfluous; if you are needing to use a cast because the type of the pixels member of SDL_Surface actually isn't Uint8, are you sure it is a good idea? And can't you use reinterpret_cast<Uint8>(screen->pixels) instead to make it clearer?


Can you reduce your problem to code analogous to this that still shows the actual error?

于 2013-06-30T16:38:59.573 回答