C++ 错误:静态成员函数中成员的无效使用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17391853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Error: invalid use of member in static member function
提问by David Gomes
I have two classes, and this is the header of one of them:
我有两个类,这是其中一个类的标题:
#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
I am calling Wrapper::set_screen(screen) from another file and I get this error:
我正在从另一个文件调用 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
I also get a similar error for the definition of every single function on Wrapper.cpp, for example:
对于 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;
}
On compile:
编译时:
/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
I know it's related to the class being static and thus the variable Wrapper.screen is not accessible or something, but I'm not sure of how to fix it. Any ideas?
我知道这与静态类有关,因此变量 Wrapper.screen 不可访问或其他东西,但我不确定如何修复它。有任何想法吗?
回答by user2536820
You are using a static variable
您正在使用静态变量
static SDL_Surface *screen;
in your code.
在你的代码中。
In C++ when you declare a static variable in the .h (or .hpp) you are creating a variable that is general (static) to the class. Thus, to use it in another file you have to redeclare it (which I'm guessing you didn't) to create a variable in that file referencing the static one. In your case put this:
在 C++ 中,当您在 .h(或 .hpp)中声明静态变量时,您正在创建一个对类通用(静态)的变量。因此,要在另一个文件中使用它,您必须重新声明它(我猜您没有)以在该文件中创建一个引用静态变量的变量。在你的情况下,把这个:
SDL_Surface* Wrapper::screen;
in the .cpp file.
在.cpp 文件中。
I'm not sure the theory is well explained, but it works like that.
我不确定这个理论是否得到很好的解释,但它是这样工作的。
回答by asafrob
Your class and member (screen) are not static, which means they don't actually exist. You can't access a non static member in a static function.
您的类和成员(屏幕)不是静态的,这意味着它们实际上并不存在。您不能访问静态函数中的非静态成员。
Try to make your data members to be static.
尽量让你的数据成员是静态的。
回答by Jonathan Leffler
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.
你的头文件不应该包含using namespace std;
——它不使用或声明std
命名空间中的任何东西,并且指定using namespace std;
通常被认为是“不是一个好主意”,当它出现在头文件中时更是如此。
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.)
还不清楚您的标题是否需要包含SDL/SDL.h
. 如果Uint8
类型很容易隔离(不一定有效),那么您的头文件可以简单地使用类的前向声明SDL_Surface
。(您的实现代码将需要包含SDL/SDL.h
;#include
但当简单的前向声明就足够了时,您不应该用不必要的指令给包装类的用户带来负担。)
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?
它也可以在没有警告的情况下编译。的(Uint8 *)
铸造(从原来的复制)是不必要的。根据给出的类定义,它是多余的;如果您需要使用强制转换,因为pixels
成员的类型SDL_Surface
实际上不是Uint8
,您确定这是一个好主意吗?你不能用reinterpret_cast<Uint8>(screen->pixels)
它来让它更清楚吗?
Can you reduce your problem to code analogous to this that still shows the actual error?
您能否将问题简化为与此类似但仍显示实际错误的代码?