-2

以下用 g++ 编译得很好:

struct acounter {

  long static counter;

  void static create() {  //reset or create the counter
    counter=0;
  }

  void static count() {   //the counter changes its internal value.
    counter=counter + 1;
  }   

};


int main(int   argc,  char *argv[] ){    //compiles and executes!
  //do some random stuff...
  return 0;
}

问题是:只要我添加“acounter::create();” 或“acounter::count();” 到主循环,我得到一个错误:

未定义对“acounter::counter”的引用

但我定义了“计数器”,甚至初始化了它。问题是什么?

(PS 我只能使用静态函数,因为我必须稍后处理回调 - 想法是仅在其全局范围内使用整个结构而不创建实例。)

4

2 回答 2

2

静态类成员需要定义和声明。当我们这样做时,我们可以将静态成员初始化为正确的值,因此不再需要“创建”——但我们可以有一个“重置”逻辑。

此外,如果您实际上是通过静态函数公开逻辑,则计数器本身应该是私有的。

最后,作为风格问题,static关键字通常放在类型名称之前。这是一个品味问题,但它是一个相当重要的属性,在查看类定义时应该能够快速区分静态和非静态成员。

struct acounter
{
private:
  static long counter;
public:
  static void reset() { counter = 0; }
  static void count() { ++counter; }
};

long acounter::counter = 0;   // definition and initial value

int main()
{
  acounter::count();
}
于 2013-10-13T11:33:35.767 回答
0

将其放入*.cpp

long acounter::counter;

注意:您可能还想初始化它,例如:

long acounter::counter = 0;

static,但非const数据成员应该在类/结构定义之外和包含类/结构的命名空间内定义。通常的做法是在翻译单元 ( *.cpp) 中定义它,因为它被认为是一个实现细节。

摘自C++ 标准的第 9.4.2 节

静态数据成员的定义应出现在包含该成员的类定义的命名空间范围内。

还有另一种方式。只有staticconst整型可以同时声明和定义(在类/结构定义中):

class Example {
public:
  static const long x = 101;
};

在这种情况下,您不需要添加x定义,因为它已经在类/结构定义中定义。在您的情况下,long是整数类型,但不是const,因此您不能选择这种方法。

于 2013-10-13T11:34:51.787 回答