我有两个类,这是其中一个类的标题:
#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不可访问或者其他东西,但我不确定如何修复它。有什么想法吗?
答案 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}}来使其更清晰?
您是否可以将问题减少到类似于仍然显示实际错误的代码?