【问题标题】:A non-static member reference of a variable inside a class' static function类的静态函数中变量的非静态成员引用
【发布时间】:2014-05-05 09:19:55
【问题描述】:

我想将 OpenGL 功能从主源文件转移到一个单独的类中。

// Initialize rendering (GLUT and GLEW)
gfxMgr.init(argc, argv);
...
glutReshapeFunc(gfxMgr.resizeWindow);
glutKeyboardFunc(gfxMgr.keyPressed);
glutKeyboardUpFunc(gfxMgr.keyReleased);

问题始于在类的实现文件中定义回调函数。我在头文件中将它们声明为静态的。

static void init(int , char** );
...
static void drawScene();
static void whenIdle();

然后另一个问题接踵而至。我想在我的实现文件的一个静态函数中使用非静态布尔 fullScreen 变量(如在标题中声明的),但 IDE 告诉我“非静态成员引用必须相对于特定对象” .

void GfxMgr::init(int argc, char** argv)
{
    ...
    if(fullScr) glutFullScreen();
    ...
}

我不明白这个问题,我不知道该怎么办。我将布尔值和其他一些变量声明为静态变量,但出现了一堆未解决的外部符号错误。

【问题讨论】:

  • 如果非static成员函数未绑定到类的具体对象,则不能调用它。
  • glutFullScreen();也是这个类的静态成员函数吗?
  • @40two :好吧,现在我已经将这些函数声明为静态(正如我在 OP 中提到的)。如果不是,我确实使用gfxMgr. 来调用这些函数。
  • @πάνταῥεῖ:不。我没有对 glutFullScreen() 做任何事情,我只是调用了一次。

标签: c++ oop opengl static callback


【解决方案1】:

我不明白这个问题

您需要了解什么是静态成员函数。例如,请参阅this tutorial。我也推荐上一篇关于静态成员变量的文章。

简而言之,静态成员函数对类的实例一无所知。非静态成员变量绑定到类的实例。因此,静态成员函数无法使用非静态成员变量。

我不知道该怎么办。

你应该做什么取决于你的类和它的功能应该做什么。

  • 如果函数的行为应该依赖于实例的成员变量的值,那么函数必须是非静态的,并且您必须在实例上调用它。
  • 如果函数应该只依赖于类的全局状态而不是实例,那么函数访问的变量必须是该全局状态的一部分(静态成员)。

C 回调不能是成员函数。因此它们不能依赖于实例的状态(全局实例除外,请参阅this tutorial

【讨论】:

  • 好的。我已将一些函数改回非静态,但改为:error C3867: 'GfxMgr::drawScene': function call missing argument list; use '&GfxMgr::drawScene' to create a pointer to member。由于它是回调,它不应该有任何参数,而且我已经在这个问题上摆弄了足够多的指针。
  • @Andrey:现在你遇到了问题,C++ 类成员函数不能用作 C 风格回调的回调。您需要在 GLUT 窗口和类实例之间创建一些关联。
  • @Andrey,请参阅我的回答中的第二个教程,3.5 的第一个示例是 thunking。但是,如果 gl 回调注册不允许将任意指针传递给回调函数,则不能使用该选项。在这种情况下,您必须使用静态成员或使用全局实例的辅助函数。
  • @Andrey:您需要一些映射,从 GLUT 窗口 int glutGetWindow(void) 到与该窗口关联的 GfxMgr 类实例。我建议使用std::map<int, GfxMgr*> 类型的静态类成员,并在GfxMgr::init 中调用glutCreateWindow 之后,在注册回调之前添加一个从GLUT 窗口到类实例window_map[glutGetWindow()] = this; 的新映射。然后在静态回调函数中将静态蹦床包装到类实例方法static void GfxMgr::s_display(){window_map[glutGetWindow()]->display();}
  • @Andrey,你必须像示例 B 中那样做。它有一个静态成员函数 TClassB::Wrapper_To_Call_Display(char* string) 作为回调。要进行不带参数的回调,只需将参数省略即可。静态成员在全局实例上调用非静态成员函数。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 2021-12-03
  • 2016-05-20
  • 1970-01-01
  • 1970-01-01
  • 2020-08-09
  • 2011-09-07
相关资源
最近更新 更多