【问题标题】:Error: invalid use of member in static member function错误:静态成员函数中成员的无效使用
【发布时间】:2013-06-27 19:54:18
【问题描述】:

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

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

【问题讨论】:

  • 它应该可以工作...你能发布一个最小的完整示例吗?
  • 您似乎正在尝试访问静态函数内的非静态成员屏幕。你不能这样做,因为静态成员函数不是通过 this 指针隐式传递的。因此,除非您以某种方式使类实例可用于静态函数,否则您无法像在非静态成员函数中那样访问非静态成员。
  • 刚刚注意到您将成员更改为指针。确保重新编译源代码。

标签: c++ class oop


【解决方案1】:

您正在使用静态变量

static SDL_Surface *screen;

在您的代码中。

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

SDL_Surface* Wrapper::screen;

.cpp 文件中。

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

【讨论】:

    【解决方案2】:

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

    尽量让你的数据成员是静态的。

    【讨论】:

    • 作为一个已经尝试学习 C++ 一段时间的人,并且编写了我从未在任何地方使用过“静态”一词的代码,我编写的代码实际上并没有退出的消息是莫名其妙。是什么导致它们的输出出现?
    【解决方案3】:

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

    您的标题不应包含 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 *) 演员表(从原版复制)是不必要的。给出的类定义是多余的;如果您需要使用演员表,因为SDL_Surfacepixels 成员的类型实际上不是Uint8,您确定这是个好主意吗?你不能用reinterpret_cast&lt;Uint8&gt;(screen-&gt;pixels) 来让它更清楚吗?


    您能否将问题简化为与此类似但仍显示实际错误的代码?

    【讨论】:

      猜你喜欢
      • 2018-12-01
      • 1970-01-01
      • 1970-01-01
      • 2019-05-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-26
      相关资源
      最近更新 更多