Неразрешенный внешний символ на статических членах класса - PullRequest
120 голосов
/ 12 октября 2008

Очень просто:

У меня есть класс, который состоит в основном из статических открытых членов, поэтому я могу сгруппировать похожие функции, которые все еще должны вызываться из других классов / функций.

В любом случае, я определил две статические переменные типа unsigned в своей публичной области видимости. Когда я пытаюсь изменить эти значения в конструкторе того же класса, я получаю ошибку «неразрешенный внешний символ» при компиляции.

class test 
{
public:
    static unsigned char X;
    static unsigned char Y;

    ...

    test();
};

test::test() 
{
    X = 1;
    Y = 2;
}

Я новичок в C ++, так что будьте спокойны со мной. Почему я не могу этого сделать?

Ответы [ 4 ]

133 голосов
/ 12 октября 2008

Вы забыли добавить определения, соответствующие вашим объявлениям X и Y

unsigned char test::X;
unsigned char test::Y;

где-то. Вы также можете инициализировать статический член

unsigned char test::X = 4;

и снова вы делаете это в определении (обычно в файле CXX), а не в объявлении (которое часто находится в файле .H)

59 голосов
/ 12 октября 2008

Объявления членов статических данных в объявлении класса не являются их определением. Чтобы определить их, вы должны сделать это в файле .CPP, чтобы избежать дублирования символов.

Единственные данные, которые вы можете объявить и определить, - это целочисленные статические константы. (Значения enums также могут использоваться как постоянные значения)

Возможно, вы захотите переписать ваш код как:

class test {
public:
  const static unsigned char X = 1;
  const static unsigned char Y = 2;
  ...
  test();
};

test::test() {
}

Если вы хотите иметь возможность изменять ваши статические переменные (другими словами, когда нецелесообразно объявлять их как const), вы можете разделить код между .H и .CPP следующим образом:

.H:

class test {
public:

  static unsigned char X;
  static unsigned char Y;

  ...

  test();
};

.CPP:

unsigned char test::X = 1;
unsigned char test::Y = 2;

test::test()
{
  // constructor is empty.
  // We don't initialize static data member here, 
  // because static data initialization will happen on every constructor call.
}
3 голосов
/ 04 мая 2018

Так как это первый SO поток, который мне показался при поиске «неразрешенных внешних элементов со статическими константными членами» в целом, я оставлю еще одну подсказку, чтобы решить одну проблему с неразрешенными внешними объектами:

Для меня вещь, которую я забыл, состояла в том, чтобы пометить определение моего класса __declspec(dllexport), и при вызове из другого класса (за пределами dll этого класса) я, конечно, получил свою неразрешенную внешнюю ошибку.
Тем не менее, легко забыть, когда вы меняете внутренний вспомогательный класс на класс, доступный из других источников, поэтому, если вы работаете в динамически связанном проекте, вы также можете проверить это тоже.

1 голос
/ 19 сентября 2018

в моем случае я объявил одну статическую переменную в файле .h, как

//myClass.h
class myClass
{
static int m_nMyVar;
static void myFunc();
}

и в myClass.cpp я пытался использовать этот m_nMyVar. Он получил ошибку ССЫЛКИ, как:

ошибка LNK2001: неразрешенный внешний символ "public: static class ... Файл cpp, связанный с ошибкой ссылки, выглядит так:

//myClass.cpp
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

Поэтому я добавляю ниже код в верхней части myClass.cpp

//myClass.cpp
int myClass::m_nMyVar; //it seems redefine m_nMyVar, but it works well
void myClass::myFunc()
{
myClass::m_nMyVar = 123; //I tried to use this m_nMyVar here and got link error
}

тогда LNK2001 ушел.

...