在c++中使用静态属性

Using static attributes in c++?

本文关键字:静态 属性 c++      更新时间:2023-10-16

我有一个任务,我需要从不同的文档中读取单词,并将它们存储在一个字符串向量中,我将这个向量设置为静态的,这样每个文档都可以将它们的单词添加到向量中,这样我就可以有一个所有单词的列表。我制作了一个文档类,并在标题中写道:

class document {
public:
    document(string filename);
    static vector<string> words;
    string name;
    vector<int> frequency;
    void getFrequency();
    static void  addWord(string wordd); 

在document.cpp文件中,使用以下内容实现了addWord方法:

 static void  document::addWord(string wordd){

    vector<string>::iterator i = find(words.begin(), words.end(), wordd);
    if (i == words.end()) {
        words.push_back(wordd);
    }
 }

然而,这不起作用,每次我试图构建代码时,它都会给我这个错误消息

"/usr/bin/make" -f nbproject/Makefile-Debug.mk QMAKE= SUBPROJECTS= .build-conf "/usr/bin/make"  -f nbproject/Makefile-Debug.mk dist/Debug/GNU-MacOSX/assignment1 mkdir -p build/Debug/GNU-MacOSX rm
-f build/Debug/GNU-MacOSX/main.o.d g++    -c -g -MMD -MP -MF build/Debug/GNU-MacOSX/main.o.d -o build/Debug/GNU-MacOSX/main.o main.cpp mkdir -p dist/Debug/GNU-MacOSX g++     -o dist/Debug/GNU-MacOSX/assignment1 build/Debug/GNU-MacOSX/main.o   Undefined symbols for architecture x86_64:   "document::words", referenced from:
      document::getFrequency()      in main.o
      document::addWord(std::basic_string<char, std::char_traits<char>, std::allocator<char> >)in main.o ld: symbol(s) not found for architecture x86_64 collect2: ld returned 1 exit status make[2]: *** [dist/Debug/GNU-MacOSX/assignment1] Error 1 make[1]: *** [.build-conf] Error 2 make: *** [.build-impl] Error 2

BUILD FAILED (exit value 2, total time: 1s)

此错误消息所涉及的即时错误是您已经声明了document::words,但尚未定义它。它的定义存在于类定义之外,通常在类的翻译单元中。你需要有这样的定义:

static std::vector<std::string> document::words;

也就是说,请不要说静态数据很像控制得稍微好一点的全球数据。尤其是在并发程序中,所有对象都有共享的东西,这是一个坏主意。如果这个东西是可变的,那就更糟糕了(顺便说一句,如果全局数据被称为"Singleton",这也适用:仅仅因为某个东西据称是一种设计模式,并不意味着它在某种程度上是幸运的,问题就消失了)。

从函数定义(.cpp文件)中删除关键字static

当函数定义中使用static时,该词的含义是函数仅在当前编译单元中可见(类似于未命名的命名空间)。因此,只需将其从.cpp.

中删除即可

Undefined symbols for architecture x86_64:   "document::words"

告诉您静态数据成员实际上从未创建:您在头中声明了它,但从未告诉编译器将对象存储在哪里。

在您的情况下,这是一个没有问题的问题,但在一个具有许多.cpp文件(包括相同头)的大型项目中,只分配一次静态对象是很重要的。

将此行添加到document.cpp:

vector<string> document::words;

除了作用域名称之外,它与全局变量声明完全一样(因为静态成员就是这样)。