Проблемы с пониманием stati c в файлах заголовков (встроенные) - PullRequest
0 голосов
/ 01 августа 2020

Я довольно давно работаю со stati c, но теперь, когда приходят файлы заголовков, я немного запутался.

Основная проблема в этом коде:

#include <iostream>
#include <string>
#include <sstream>
#include <set>
#ifndef WORD_H
#define WORD_H

#include<unordered_map>

class Word
{
private:
    std::string word;
    int k;

    static std::unordered_map<std::string, int> x;
public:

    Word(std::string word) : word(word)
    {
        if (x.find(word) != x.end())
            x.insert({ word , 0 });
        else
        {
            x[word]++;
        }
    }

    std::string getWord() const
    {
        return x.find(this->word)->first;
    }

    int getCount() const
    {
        return x.find(this->word)->second;
    }
    friend bool operator<(const Word& a, const Word& b);
};

bool operator<(const Word& a, const Word& b)
{
    return a.getWord() < b.getWord();
}

#endif

std::ostream& operator<<(std::ostream& out, const Word& w) {
    return out << w.getWord() << " " << w.getCount();
}

void printWordCounts(const std::string& line) {
    std::istringstream lineIn(line);
    std::set<Word> words;
    std::string wordStr;
    while (lineIn >> wordStr) {
        words.insert(Word(wordStr));
    }

    for (Word w : words) {
        std::cout << w << std::endl;
    }
}

int main() {
    std::string line;

    std::getline(std::cin, line);
    printWordCounts(line);

    std::cout << "---" << std::endl;

    std::getline(std::cin, line);
    printWordCounts(line);

    return 0;
}

Я знаю, что есть проблема с ключевым словом static, но что именно?

Кроме того, эта ошибка - одна из моих любимых. Эти ошибки между компоновщиком и STL:

Ошибка LNK2001 неразрешенный внешний символ "private: stati c class std :: unordered_map , интервал, структура std :: ha sh >, struct std :: equal_to >, класс std :: allocator const, int>>> Word :: x "(? x@Word@@0V? $unordered_map@V?$basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@HU? $hash@V?$basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@@2@U? $equal_to@V?$basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@@2@V? $allocator@U? $ pair @ $$ CBV? $basic_string@DU?$char_traits@D@std@@V? $allocator@D@2@@std@@H@std@@@2@@std@@A) ConsoleApplication63 C: \ Users \ Ivo \ source \ repos \ ConsoleApplication63 \ ConsoleApplication63 \ ConsoleApplication63. obj 1

Я надеюсь, что кто-нибудь сможет дать мне объяснение.

Ответы [ 2 ]

5 голосов
/ 01 августа 2020

У вас есть только объявленный член static x. Вам также необходимо определить это вне класса следующим образом:

std::unordered_map<std::string, int> Word::x;

Начиная с C ++ 17, вы можете определить x внутри определения класса следующим образом:

inline static std::unordered_map<std::string, int> x;
0 голосов
/ 01 августа 2020

Stati c Объявления переменных в классах идентичны объявлению глобальной переменной в файле заголовка, за исключением того, что «символ» находится в пространстве имен класса, и поэтому доступ к нему защищен уровнями видимости. Это означает, что, как и объявления глобальных переменных, объявления переменных класса stati c имеют `` слабую '' связь, и блок компиляции должен определять определение символа, чтобы компоновщик мог ie память, связанную с объявлениями переменных в других файлах. ровно одной переменной.

Определение переменной stati c выполняется вне класса, например:

// <variable type> <class type>::<variable name>;
std::unordered_map<std::string, int> Word::x;

Обратите внимание, что только один файл. cpp должен определять переменную

...