C++ - 为什么这个成员需要声明为static?

Sam*_*Sam 1 c++ static-members

这让我疯了.我得到一个"没有匹配函数调用'WordCloud :: WordCloud()'"错误.似乎正在调用默认构造函数,但由于我没有定义一个,因此抛出了错误.

构造函数是:

WordCloud( map<string, int> *source ); 
Run Code Online (Sandbox Code Playgroud)

在主cpp文件中,错误发生在指示的行上

class FontTestingApp : public AppBasic 
{                                      // <-- error was appearing on this line
public:
  void setup();
  void mouseDown( MouseEvent event ); 
  void update();
  void draw();

  map<string, int> wordList;
  WordCloud wc;        // comment out this line and it compiles
};
Run Code Online (Sandbox Code Playgroud)

所以,我猜测在实例化FontTestingApp类时实例化了一个WordCloud对象.

如果我注释掉这条线

WordCloud wc;
Run Code Online (Sandbox Code Playgroud)

然后它编译.

为了解决它,我终于将线路改为

static WordCloud wc;
Run Code Online (Sandbox Code Playgroud)

那编译.

我真的不知道为什么,而且这还不够好:)如果有人能解释这里发生了什么,我会非常感激.我顺便使用libCinder(libcinder.org)

bdo*_*lan 5

在构造包含对象时,实例化类中的非静态成员变量(即,调用它们的构造函数).默认情况下,调用零参数默认构造函数 - 但如果您不提供任何显式构造函数,则编译器仅为您提供此参数.

解决方案是wc在FontTestingApp构造函数中显式构造对象:

FontTestingApp::FontTestingApp()
    : wc(&wordList)
{ /* ... */ }
Run Code Online (Sandbox Code Playgroud)

至于为什么static变化抑制了错误,声明static WordCloud wc;中的类定义不实例化对象; 它只是声明它,与extern WordCloud wc;at文件范围不会实例化类完全相同.实际上,静态成员变量与extern全局变量基本相同,只是它们的名称和访问控制规则基于它们所在的类.

您是否在某些.cpp文件中实际实例化了静态成员变量:

WordCloud FontTestingApp::wc;
Run Code Online (Sandbox Code Playgroud)

然后你会有一个错误.当然,您可以传递构造函数参数来解决此问题:

static map<string, int> dummy_word_source;
WordCloud FontTestingApp::wc(&dummy_word_source);
Run Code Online (Sandbox Code Playgroud)

请注意,如果您根本没有实例化变量,那么如果您尝试在别处引用它,您当然会收到链接器错误.