3

Есть класс.

class some{
public:
    static int Instances;
    static int TotalSumm;
public:
    some() {  // Конструктор
        Instances = 0;
    }
}

Этот код не собирается. Ошибка:

LNK2001 "неразрешённый внешний символ".

В чём может быть проблема?

Nicolas Chabanovsky
  • 51,426
  • 87
  • 267
  • 507
  • Проблема у вас в дизайне приложения. Статические поля в классах - редкостная трудноотлаживаемая мерзость. – gbg May 22 '16 at 06:52

2 Answers2

3

Вы объявили статическое поле. Но не определили.

Добавьте

int some::Instances;
int some::TotalSumm;

вне класса.

Вдогонку - вам точно надо обнулять член класса при создании каждого экземпляра?

Update. Дабы не нарушать правило одного определения, эти определения должны располагаться в .cpp-файле, в единственном экземпляре. При их размещении в заголовочном файле они будут определены в каждом .cpp- файле проекта...

Harry
  • 221,325
  • Нет, не надо обнулять член класса. Это просто пример, реальная задача немножко другая. Не хотелось, что бы код можно было найти через поисковики. Но ваш ответ, мне всё равно очень помог.
    А можно как нибудь проинициализировать поле из класса? Например механизмы схожие со статическим конструктором из C#?
    – user211023 May 21 '16 at 09:32
  • Если вам нужна инициализация - просто инициализируете при определении. Типа int some::Instances{5}; или int some::Instances = func(); или, если это что-то серьезнее и имеет свой конструктор - как при определении объекта соответствующего класса. Например, пусть есть класс test с конструктором от двух int, и в классе static test T; - тогда определяете как test some::T{12,18}; или типа того... – Harry May 21 '16 at 09:44
  • Добавьте, что это нужно делать в cpp файле, иначе очень быстро придёт odr-violation. – ixSci May 21 '16 at 10:33
  • @ixSci Это будет вторым вопросом :) Может, у человека все в одном файле? :) – Harry May 21 '16 at 10:56
  • Сейчас в одном, завтра в двух. Не кажется Вам, что это всё-таки стоит упомянуть? Ведь это поможет человеку в дальнейшем. На мой взгляд, это должно быть частью ответа, на такой тривиальный вопрос. – ixSci May 21 '16 at 10:58
  • @ixSci OK, добавил – Harry May 21 '16 at 11:01
  • @ixSci, а #pragma once не поможет при объявлении в h-файле? – Qwertiy May 21 '16 at 11:23
  • @Qwertiy Нет, не тот случай. В каждый .cpp-файл все равно войдет - пусть и по одному разу :) – Harry May 21 '16 at 11:27
  • @Harry, да.. Что-то я не подумал, что cpp тоже много :) – Qwertiy May 21 '16 at 11:28
0

потому что нужно проинициализировать за пределами класса

class some{
public:
    static int Instances;
    static int TotalSumm;
public:
    some()
    {  
        Instances = 0;
    }
};

int some::Instances = 0;

int main(int argc, char *argv[])
{
    some::Instances = 5;
    return 0;
}
Qwertiy
  • 123,725
  • Инициализировать не обязательно, это не константное поле. А вот определить - да, обязательно... – Harry May 21 '16 at 09:28
  • А можно как нибудь проинициализировать поле из класса? Например механизмы схожие со статическим конструктором из C#? – user211023 May 21 '16 at 09:30
  • @user211023, аналога статического конструктора в C++ нет, но подобного поведения можно добиться. Посмотрите вот этот ответ – ixSci May 21 '16 at 10:49