错误:在静态成员函数中无效使用成员

时间:2013-06-30 15:17:34

标签: c++ class oop

我有两个类,这是其中一个类的标题:

#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(屏幕),我收到此错误:

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不可访问或者其他东西,但我不确定如何修复它。有什么想法吗?

3 个答案:

答案 0 :(得分:5)

您正在使用静态变量

static SDL_Surface *screen;

代码。

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

SDL_Surface* Wrapper::screen;
.cpp文件中的

我不确定这个理论是否得到了很好的解释,但它的确如此。

答案 1 :(得分:0)

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

尝试让您的数据成员保持静态。

答案 2 :(得分:0)

我不相信你向我们展示的代码摘要是对你的问题的准确描述。

您的标头不应包含using namespace std; - 它不会使用或声明std命名空间中的任何内容,并且指定using namespace std;通常被视为“不是一个好主意”,加倍所以当它出现在头文件中时。

还不清楚您的标头是否需要包含SDL/SDL.h。如果Uint8类型很容易被隔离(不一定有效),那么您的头文件可以简单地使用SDL_Surface类的前向声明。 (您的实现代码需要包含SDL/SDL.h;但是当简单的前向声明就足够时,您不应该使用不必要的#include指令给包装类的用户带来负担。)

此代码是自包含的(不需要任何标题),但或多或​​少模拟了您可以使用的内容,并且编译正常:

#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;
}

它也会在没有警告的情况下编译。 (Uint8 *)演员表(从原件复制)是不必要的。给定类定义,它是多余的;如果您因为pixels SDL_Surface Uint8成员的类型实际上不是reinterpret_cast<Uint8>(screen->pixels)而需要使用强制转换,您确定这是个好主意吗?您是否可以使用{{1}}来使其更清晰?


您是否可以将问题减少到类似于仍然显示实际错误的代码?