Использование статических атрибутов в C ++? - PullRequest
1 голос
/ 06 февраля 2012

У меня есть задание, в котором мне нужно прочитать слова из разных документов и сохранить их в векторе строк, я сделал этот вектор статическим, чтобы каждый документ просто добавил свои слова в вектор, чтобы у меня был один список из всех слов. я сделал класс документа и в шапке написал:

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)

Ответы [ 3 ]

2 голосов
/ 06 февраля 2012

Непосредственная ошибка, о которой говорится в этом сообщении об ошибке, заключается в том, что вы объявили document::words, но не определили его.Определение этого живет вне определения класса, как правило, в единице перевода класса.Вам нужно иметь определение, которое выглядит примерно так:

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

При этом, пожалуйста, не говорите, что статические данные во многом похожи на немного лучше управляемые глобальные данные.Особенно в параллельных программах, имеющих что-то, что является общим для всех объектов, это плохая идея.Если эта вещь изменчива, это еще более плохая идея (кстати, она также применима, если глобальные данные упоминаются как «синглтон»: просто потому, что что-то, как утверждается, является шаблоном проектирования, не означает, что оно каким-то образом благословлено, и проблемы исчезли)езды).

0 голосов
/ 06 февраля 2012

Строка

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

сообщает вам, что ваш статический элемент данных никогда не создавался: вы объявили его в заголовке, но никогда не указывали компилятору, где хранить объект.

Это не проблема в вашем случае, но в более крупном проекте с большим количеством .cpp файлов, включая один и тот же заголовок, важно, чтобы статический объект выделялся только один раз.

Добавьте эту строку в document.cpp:

vector<string> document::words;

Это похоже на объявление глобальной переменной (поскольку это действительно статический член), за исключением имени с областью действия.

0 голосов
/ 06 февраля 2012

Удалить ключевое слово static из определения функции (из файла .cpp).

Если в определении функции используется static, то значение слова в том, что функция видна только в текущей единице компиляции (аналогично безымянному пространству имен). Итак, просто удалите его из .cpp.

...